web-dev-qa-db-ja.com

Android

私はAndroidのリストビューで動作するアプリケーションを作成していますが、選択した(ハッキングされた)アイテムの背景が異なるようにアプリケーションを作成できません。私はCHOICE_MODE_SINGLEを使用しています。これは私のコードがこれまでにどのように見えるかです:


私が使用するListView:
(内部layout.xml

<ListView
    Android:id="@+id/listView"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:choiceMode="singleChoice"
    Android:listSelector="@drawable/selector_test" >
</ListView>

アダプターで使用するTextViewレイアウト:
listItem.xml

<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/listItem"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:textSize="23sp"
    Android:textStyle="bold" />

これは私がアダプターを追加する場所です:

mListAdapter = new ArrayAdapter<String>(this, R.layout.listItem, mList);
mListView = (ListView) findViewById(R.id.listView);
mListView.setAdapter(mAuthorAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        String selected = mList.get(position);
        // ...
        mListView.setItemChecked(position, true);
    }
});

GetCheckedItemPosition()を呼び出すと適切な値が返されるため、クリック時に適切な項目がチェックされると確信しています。


そして、チェックされた項目を強調するために私が試みた2つのこと:


セレクタードローアブル:
selector_test.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:enterFadeDuration="@Android:integer/config_longAnimTime">

    <item Android:state_checked="true"><shape>
            <solid Android:color="@color/red" />
        </shape></item>
    <item Android:state_selected="true"><shape>
            <solid Android:color="@color/blue" />
        </shape></item>
    <item Android:state_pressed="true"><shape>
            <solid Android:color="@color/green" />
        </shape></item>

</selector>

私はそれを.xmlに追加します:

Android:listSelector="@drawable/selector_test"

背景ドローアブル:
background_test.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@color/red" Android:state_checked="true"/>
    <item Android:drawable="@color/blue" Android:state_selected="true"/>
    <item Android:drawable="@color/green"/>

</selector>

私はそれを.xmlに追加します:

Android:background="@drawable/background_test"

ListView.xmlとlistItem.xmlの両方にセレクターと背景を追加してみましたが、変更されるのは、デフォルトの背景色と、アイテムが押された(または保持された)ときのセレクターの色だけです。
Android:state_checked = "true"およびAndroid:state_selected = "true"は何もしないようです。

ビューが選択されている場合、ArrayAdapterのgetView()メソッドをオーバーライドし、その中でsetBackgroundColor()を呼び出すことで背景を変更できます。これにより、背景が変更されますが、セレクターも完全に削除されます。また、特に同じことを別の方法で実現できる場合は、コードを1行変更するためだけにクラスをオーバーライドすることはあまり好きではありません。

だから私が求めているのは、セレクターまたはバックグラウンドドローアブルをそれに追加することによって、ListViewでチェックされた項目を強調表示する方法があり、それを間違っている、またはいくつか機能させる必要がある他の方法。

よろしくお願いします!:)

8
Velja

あなたの活動のonStartにこの行を追加してください

lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

ここで、lvはlistViewのインスタンスです

次に、このメソッドをオーバーライドして、次の行を追加します。

 @Override
public void onListItemClick(ListView l, View v, int position, long id) {


    // Set the item as checked to be highlighted 
    lv.setItemChecked(position, true);
            v.setBackgroundColor(Color.BLUE);

        conversationAdapter.notifyDataSetChanged();

}

次に、カスタムアダプターのgetViewメソッドで、前に選択したアイテムの背景の色を通常に戻します。

8

これを試して:

listViewDay.setItemChecked(position, true);
listViewDay.setSelection(position);

listitem.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="40dp"
    Android:background="@drawable/list_day_selector" >

    <TextView
        Android:id="@+id/txtItemDay"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:gravity="center_vertical|center_horizontal"
        Android:text="22"
        Android:textColor="@Android:color/white"
        Android:textSize="22sp" />

</LinearLayout>

list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@drawable/list_item_bg_normal" Android:state_activated="false"/>
    <item Android:drawable="@drawable/bg_with_left_arrow" Android:state_pressed="true"/>
    <item Android:drawable="@drawable/bg_with_left_arrow" Android:state_activated="true"/>

</selector>
5
Luc

プログラムでは、setSelectorを使用します。例えば:

lv.setSelector(R.color.abc_background_cache_hint_selector_material_dark);

次のようにセレクターでアイテムの状態を設定します。

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_activated="true"
        Android:color="@color/XXX/>
</selector>

state_checkedが機能しない理由がわかりません。最初はCheckableviewである必要があると思ったので、CheckedTextViewを試しました。まだ動かない。
とにかくstate_activatedで問題が解決します。

0
limmeng

セレクターが汚れたストライプを残すなど、次々とグリッチに遭遇した数時間後、私は自分でそれを行うことにしました。

class MyListAdapter extends ArrayAdapter<MyData> {
    // !!! access to the current selection
    int mSelected = 0;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v =  super.getView(position, convertView, parent);
        // !!! this is where the selected item is highlighted
        v.findViewById(R.id.selectionSign).setVisibility(position == mSelected ? View.VISIBLE : View.INVISIBLE);
        return v;
    }
    public CommandListAdapter(Context context, List<MyData> objects) {
        super(context, R.layout.mylistitem, R.id.mytext, objects);
    }
}

onItemClickListener:

        mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                setSelectionPosNoUpd(position);
                update();
            }
        });

および次のように定義された関数:

    void setSelectionPosNoUpd(int n) {
        mCommandListAdapter.mSelected = n;
        //update();
    }
    void update() {
        mListViewOfCommands.smoothScrollToPosition(getSelectionPos());
        mCommandListAdapter.notifyDataSetChanged();
    }

リストアイテムXML(res/layout/mylistitem.xml)は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    >
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:orientation="vertical" >
        <TextView
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/mytext" 
        />
    </LinearLayout>
    <View
        Android:id="@+id/selectionSign"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#10ff5000"
        Android:visibility="invisible"
        />
</FrameLayout>

欠点は、選択を変更した後にpdate()を実行する必要があることです。以前にハイライトされたビューのハイライトを解除する簡単な方法はありません。