Android의 항목에 대한 사용자 지정 ListView 클릭 문제

그래서 사용자 지정 ListView 개체가 있습니다. 목록 항목에는 두 개의 텍스트보기가 서로 쌓여 있고 실제로 무언가를 할 때까지 숨겨져있는 가로 진행률 표시 줄이 있습니다. 맨 오른쪽에는 사용자가 데이터베이스에 업데이트를 다운로드해야 할 때만 표시하려는 확인란이 있습니다. 가시성을 Visibility.GONE으로 설정하여 확인란을 비활성화하면 목록 항목을 클릭 할 수 있습니다. 체크 박스가 보이면 체크 박스를 제외하고 목록에서 아무 것도 클릭 할 수 없습니다. 몇 가지 검색을 해 보았지만 현재 상황과 관련된 것을 찾지 못했습니다. 이 질문을 찾았습니다하지만 내부적으로 데이터베이스 목록을 포함하기 위해 ArrayLists를 사용하고 있기 때문에 재정의 된 ArrayAdapter를 사용하고 있습니다. LinearLayout보기를 가져와 Tom처럼 onClickListener를 추가하면 되나요? 잘 모르겠습니다.

다음은 목록보기 행 레이아웃 XML입니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
        <TextView
            android:id="@+id/UpdateNameText"
            android:layout_width="wrap_content"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_vertical"
            />
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:id="@+id/UpdateStatusText"
            android:singleLine="true"
            android:ellipsize="marquee"
            />
        <ProgressBar android:id="@+id/UpdateProgress"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
                     android:indeterminateOnly="false"
                     android:progressDrawable="@android:drawable/progress_horizontal"
                     android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
                     android:minHeight="10dip"
                     android:maxHeight="10dip"
                     />
    </LinearLayout>
    <CheckBox android:text=""
              android:id="@+id/UpdateCheckBox"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              />
</LinearLayout>

다음은 ListActivity를 확장하는 클래스입니다. 분명히 아직 개발 중이므로 누락되었거나 남겨진 부분을 용서하십시오.

public class UpdateActivity extends ListActivity {

    AccountManager lookupDb;
    boolean allSelected;
    UpdateListAdapter list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        lookupDb = new AccountManager(this);
        lookupDb.loadUpdates();

        setContentView(R.layout.update);
        allSelected = false;

        list = new UpdateListAdapter(this, R.layout.update_row, lookupDb.getUpdateItems());
        setListAdapter(list);

        Button btnEnterRegCode = (Button)findViewById(R.id.btnUpdateRegister);
        btnEnterRegCode.setVisibility(View.GONE);

        Button btnSelectAll = (Button)findViewById(R.id.btnSelectAll);
        btnSelectAll.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                allSelected = !allSelected;

                for(int i=0; i < lookupDb.getUpdateItems().size(); i++) {
                    lookupDb.getUpdateItem(i).setSelected(!lookupDb.getUpdateItem(i).isSelected());
                }

                list.notifyDataSetChanged();
                // loop through each UpdateItem and set the selected attribute to the inverse 

            } // end onClick
        }); // end setOnClickListener

        Button btnUpdate = (Button)findViewById(R.id.btnUpdate);
        btnUpdate.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
            } // end onClick
        }); // end setOnClickListener

        lookupDb.close();
    } // end onCreate


    @Override
    protected void onDestroy() {
        super.onDestroy();

        for (UpdateItem item : lookupDb.getUpdateItems()) {
            item.getDatabase().close();
        }
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        UpdateItem item = lookupDb.getUpdateItem(position);

        if (item != null) {
            item.setSelected(!item.isSelected());
            list.notifyDataSetChanged();
        }
    }

    private class UpdateListAdapter extends ArrayAdapter<UpdateItem> {
        private List<UpdateItem> items;

        public UpdateListAdapter(Context context, int textViewResourceId, List<UpdateItem> items) {
            super(context, textViewResourceId, items);
            this.items = items;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = null;

            if (convertView == null) {
                LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = li.inflate(R.layout.update_row, null);
            } else {
                row = convertView;
            }

            UpdateItem item = items.get(position);

            if (item != null) {
                TextView upper = (TextView)row.findViewById(R.id.UpdateNameText);
                TextView lower = (TextView)row.findViewById(R.id.UpdateStatusText);
                CheckBox cb = (CheckBox)row.findViewById(R.id.UpdateCheckBox);

                upper.setText(item.getName());
                lower.setText(item.getStatusText());

                if (item.getStatusCode() == UpdateItem.UP_TO_DATE) {
                    cb.setVisibility(View.GONE);
                } else {
                    cb.setVisibility(View.VISIBLE);
                    cb.setChecked(item.isSelected());
                }

                ProgressBar pb = (ProgressBar)row.findViewById(R.id.UpdateProgress);
                pb.setVisibility(View.GONE);
            }
            return row;
        }

    } // end inner class UpdateListAdapter
}

편집 : 여전히이 문제가 있습니다. 나는 속임수를 쓰고 onClick 핸들러를 textviews에 추가하고 있지만 확인란을 클릭하지 않을 때 onListItemClick () 함수가 전혀 호출되지 않는다는 것은 매우 어리석은 것 같습니다.



답변

문제는 Android에서 포커스 가능한 요소가있는 목록 항목을 선택할 수 없다는 것입니다. 목록 항목의 확인란을 다음과 같은 속성을 갖도록 수정했습니다.

android:focusable="false"

이제 체크 박스가 포함 된 내 목록 항목 (버튼에도 작동)은 전통적인 의미에서 “선택 가능”합니다 (불이 켜지면 목록 항목의 아무 곳이나 클릭 할 수 있으며 “onListItemClick”핸들러가 실행되는 등).

편집 : 업데이트로 한 댓글 작성자가 “단추의 가시성을 변경 한 후 프로그래밍 방식으로 포커스를 다시 비활성화해야했습니다.”라고 언급했습니다.


답변

목록 항목 내에 ImageButton이 descendantFocusability있는 경우 루트 목록 항목 요소에서 값을 ‘blocksDescendants’로 설정해야합니다 .

android:descendantFocusability="blocksDescendants"

그리고 보기 에서 focusableInTouchMode플래그 .trueImageButton

android:focusableInTouchMode="true"

답변

비슷한 문제가 발생하여 CheckBox가 ListView에서 다소 까다 로움을 발견했습니다. 발생하는 일은 전체 ListItem에 대한 의지를 부과하고 일종의 onListItemClick을 재정의합니다. 이를 위해 클릭 핸들러를 구현하고 TextViews를 사용하는 대신 CheckBox에 대한 텍스트 속성도 설정할 수 있습니다.

이 View 개체도 살펴보면 CheckBox보다 더 잘 작동 할 수 있습니다.

확인 된 텍스트보기


답변

목록 항목의 루트보기에서이 행을 사용하십시오.

android : descendantFocusability = “blocksDescendants”