0

問題の有効な解決策が見つからずに、ウェブ全体をグーグルで検索した後、この質問を投稿しています。他のいくつかの投稿で議論されていることは知っていますが、どれも問題を解決するのに役立ちませんでした。

選択した項目が強調表示される ListView を実装しました。行を選択すると強調表示され、myListView.setSelection(index) を使用すると強調表示されますが、レイアウト内の他のビューをクリックすると (ボタン、チェックボックス、ラジオボタンなど)ListViewは選択を失います。

リストビューの実装方法は次のとおりです。

標準の ListView を拡張しました

public SelectableListView(Context context) {
        super(context);
        initStyle(null);
    }

    public SelectableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initStyle(attrs);
    }

    public SelectableListView(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);
        initStyle(attrs);

    }

    private void initStyle(AttributeSet attrs) {

        this.setBackgroundResource(R.drawable.red_border_fat);
        this.setPadding(3, 3, 3, 3);

        this.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                //without the following 2 lines the selection won't work 
                requestFocusFromTouch();//
                arg1.setSelected(true);
            }
        });

    }

    @Override
    public void setSelection(int position) {
            //without the following line the selection won't work 
        requestFocusFromTouch();
        super.setSelection(position);
    }

リストビューは非常に簡単な方法でレイアウトに追加されます

<my.name.space.SelectableListView
        android:layout_width="wrap_content"
        android:layout_height="100dp" >
    </my.name.space.SelectableListView>

これがアダプターです

public static SimpleAdapter GetClassAdapter(Context context,ArrayList<SeatClass> items){
        try {
            final ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
            String[] fields = new String[] { "className" };
            int[] views = new int[] { R.skin_class.lblClassDescription};
            SimpleAdapter adapter = new SimpleAdapter(context, list, R.layout.skin_class_list, fields, views);
            for (SeatClass sc : items) {
                HashMap<String, String> temp = new HashMap<String, String>();

                temp.put("className", Typologic.getClasse(sc.Id).Description);

                list.add(temp);

            }
            return adapter;
        } catch (Exception e) {
            LogHelper.WriteLogError("error in GetClassAdapter", e);
            return null;
        }

    }

これは各行のレイアウトです (R.layout.skin_class_list)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+skin_class/mainview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/selectable_listview_background_selector"
    android:orientation="horizontal">

    <TextView
        android:id="@+skin_class/lblClassDescription"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="DESCRIPTION"
        android:textColor="@drawable/selectable_listview_textcolor_selector" />

</LinearLayout>

selectable_listview_background_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">

   <item android:state_selected="true" android:state_focused="true" android:drawable="@color/black" />
   <item android:state_selected="true" android:state_focused="false" android:drawable="@color/black" />
    <item android:state_pressed="true" android:state_focused="true" android:drawable="@color/black" />
    <item android:state_pressed="true" android:state_focused="false" android:drawable="@color/black" />

    <item android:drawable="@color/White" />

</selector>

selectable_listview_textcolor_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">

   <item android:state_selected="true" android:color="@color/White" />:
    <item android:state_pressed="true" android:color="@color/White" />:
    <item android:color="@color/black" />  

</selector>

私が言ったように、これは完全に機能しますが、他のビューをクリックするとハイライトを保持できません。解決策を探して何日も探しましたが、何もうまくいかないようです。

編集:私はこの解決策を見つけました。私はもうセレクターを使用しません。ここで MyLabel は、いくつかの (この場合は関係のない) 機能を備えたカスタム TextView です。

public abstract class SelectableListView<T> extends ListView {

    protected ArrayList<T> _data;
    protected int _selectedIndex = 0;

    public SelectableListView(Context context) {
        super(context);
        initStyle(null);
    }

    public SelectableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initStyle(attrs);
    }

    public SelectableListView(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);
        initStyle(attrs);

    }

    public abstract void loadData(ArrayList<T> data);

    public T getSelectedItem() {
        if (_selectedIndex < 0)
            return null;
        else
            return _data.get(_selectedIndex);
    }

    public T getItemAt(int position) {
        if (position < 0 || position > _data.size())
            return null;
        else
            return _data.get(position);
    }

    @Override
    public void setSelection(int position) {

        colorizeSelection(position);
        super.setSelection(position);
        _selectedIndex = position;
    }


    private void colorizeSelection(int index){
        try {
            for (int i = 0; i < this.getCount(); i++) {
                if(i==index)
                    this.getChildAt(i).setBackgroundColor(getResources().getColor(R.color.Red));
                else
                    this.getChildAt(i).setBackgroundColor(getResources().getColor(R.color.White));
                ViewGroup root=(ViewGroup) this.getChildAt(i);
                colorizeSelection(root,i==index);
            }
        } catch (Exception e) {
            LogHelper.WriteLogError("error in colorizeSelection function", e);
        }
    }

    //this function is called recursively to scan all childs of a given view
    private void colorizeSelection(ViewGroup v,boolean selected){
        for (int j = 0; j < v.getChildCount(); j++) {
            if(v.getChildAt(j) instanceof ViewGroup)
                colorizeSelection((ViewGroup)v.getChildAt(j),selected);
            else if (v.getChildAt(j) instanceof MyLabel) {
                if(selected)
                    ((MyLabel)v.getChildAt(j)).setTextColor(getResources().getColor(R.color.White));
                else
                    ((MyLabel)v.getChildAt(j)).setTextColor(getResources().getColor(R.color.black));
                ((NtvLabel)v.getChildAt(j)).invalidate();
            }

        }
    }

    private void initStyle(AttributeSet attrs) {
        _selectedIndex = -1;
        this.setBackgroundResource(R.drawable.red_border_fat);
        this.setPadding(3, 3, 3, 3);

        this.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                colorizeSelection(arg2);
                _selectedIndex = arg2;

            }
        });

    }



}

私はまだより良いアプローチへの提案を待っています...いずれにせよ、これでうまくいきます:)

4

1 に答える 1

0

他のビューをクリックしたときに選択が解除された場合は、すべてを選択するコードを記述してonLostFocusListView

于 2012-12-12T15:36:25.143 に答える