3

動作中のXMLファイルをコードに変換するのに問題があります。私はListViewを持っており、実行時にその押された/チェックされたドローアブルを、高度に知られていないリソースから切り替えることができる必要があります(したがって、XMLを使用しないのはなぜですか)。

次の構成はうまく機能します。

main.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="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:choiceMode="singleChoice" >
    </ListView>

</LinearLayout>

セレクター.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/blue" android:state_pressed="true"/>
    <item android:drawable="@drawable/green" android:state_checked="true"/>
    <item android:drawable="@drawable/orange"/>
</selector>

list_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/selector"
    android:padding="10dp" />

Main.java:

public class Main extends Activity {

    StateListDrawable selector; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ListView listView1 = (ListView) findViewById(R.id.listView1);
        StringAdapter adapter = new StringAdapter(this, R.layout.list_row);
        adapter.add("one");     adapter.add("two");     adapter.add("three");       adapter.add("four");
        adapter.add("five");        adapter.add("six");     adapter.add("seven");       adapter.add("eight");
        adapter.add("nine");        adapter.add("ten");     adapter.add("eleven");      adapter.add("twelve");
        listView1.setAdapter(adapter);
    }

    private class StringAdapter extends ArrayAdapter<String>{

        public StringAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);         
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            final CheckedTextView  tv = (CheckedTextView ) inflater.inflate(R.layout.list_row, parent, false);
            tv.setText(getItem(position));
            return tv;
        }
    }
}

結果は次のようになります。これはすばらしいです(pressed:blue、checked:green、else:orange):

結果1

ただし、削除すると

android:background="@drawable/selector

list_row_xmlから、コードを介して適用します。

    Drawable blue = getResources().getDrawable(R.drawable.blue);
    Drawable green = getResources().getDrawable(R.drawable.green);
    Drawable orange = getResources().getDrawable(R.drawable.orange);

    selector = new StateListDrawable();
    selector.addState(new int[] { android.R.attr.state_pressed }, blue);
    selector.addState(new int[] { android.R.attr.state_checked }, green);
    selector.addState(new int[] { }, orange);

       tv.setBackgroundDrawable(selector);

私は次のものを取得します(すべてがstate_pressedドローアブル、青を取得します):

ここに画像の説明を入力してください

何が悪かったのか?セレクターを適切にコードに変換したと確信しています。

4

1 に答える 1

4

私はあなたのコードをコピーしましたが、すべて正常に動作します。selectorただし、 inの新しいインスタンスを必ず作成する必要がgetView()あります。それ以外の場合、すべてのアイテムに同じものを使用するとselector、1 つのアイテムを押すとすべてのアイテムに影響します。

getView()メソッドは次のようになります

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final CheckedTextView tv = (CheckedTextView) inflater.inflate(R.layout.list_row, parent, false);
        tv.setText(getItem(position));

        Drawable blue = getResources().getDrawable(R.drawable.blue);
        Drawable green = getResources().getDrawable(R.drawable.green);
        Drawable orange = getResources().getDrawable(R.drawable.orange);

        selector = new StateListDrawable();
        selector.addState(new int[] { android.R.attr.state_pressed }, blue);
        selector.addState(new int[] { android.R.attr.state_checked }, green);
        selector.addState(new int[] {}, orange);

        tv.setBackgroundDrawable(selector);

        return tv;
    }

もちろん、実行できる最適化はいくつかありますが、これは機能します。

于 2012-06-22T16:56:26.780 に答える