3

Samsung電話の単純なListViewに問題があります。

プログラムで新しいListViewを作成します。アイテムはシンプルなTextViewです。リストビューにリスナーを配置します。

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

TextView(つまり、listViewの項目)は、textColorとしてaを使用します(ColorStateList押された->緑;選択された->青;デフォルト->赤)。

エミュレーターでは、すべてが正常です。アイテムはデフォルトで赤で、1つ押すと緑になり、離すと青になります。別のアイテムを選択すると、以前に選択したものが赤に戻り、新しく選択したものが青になります。

私のSamsungデバイスの場合:アイテムはデフォルトで赤になります。1つ押すと緑になり、離すと再び赤になります(つまり、選択されていません)。

これはSamsungListView実装のバグのようです(これはカスタム実装であり、ソースコードなしで追跡するのは非常に困難です)。

編集:バグではありませんが、タッチモードのためにわずかに異なる動作です(受け入れられた回答のリンクを参照してください)

このバグ/動作を回避する方法について何かアイデアはありますか?

追加の制約:実行時にのみ使用する色を受け取るため、 xmlセレクターを使用できません。

私のデバイスはSamsungGT-B5330、API 15です(ただし、ほとんどのSamsungデバイスで発生すると思います)

これが完全な(コンパイル可能な)コードです

import android.R;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class TestActivity extends Activity {

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RelativeLayout rootLayout = new RelativeLayout(this);
    setContentView(rootLayout);

    //create listView
    ListView listView = new ListView(this);
    listView.setAdapter(new MyListAdapter());
    listView.setDivider(null);
    listView.setDividerHeight(0);
    listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    listView.setItemsCanFocus(false);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            view.setSelected(true);
        }
    });
    listView.setBackgroundColor(Color.WHITE);

    //positionning listView
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(100,200);
    lp.setMargins(50,50,10,10);
    rootLayout.addView(listView, lp);
}



private class MyListAdapter implements ListAdapter{

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ColorStateList colorStateList = new ColorStateList(
                new int[][]{
                        new int[]{R.attr.state_pressed},
                        new int[]{R.attr.state_selected},
                        new int[]{-R.attr.state_selected},
                },
                new int[]{
                        Color.GREEN,
                        Color.BLUE,
                        Color.RED});
        TextView textView = new TextView(parent.getContext());
        textView.setText("Item " + position);
        textView.setTextColor(colorStateList);
        return textView;
    }

    @Override
    public boolean areAllItemsEnabled() {
        return true;
    }

    @Override
    public boolean isEnabled(int position) {
        return true;
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
    }

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public Object getItem(int position) {
        return "data "+position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }


    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        return getCount();
    }

    @Override
    public boolean isEmpty() {
        return getCount()>0;
    }
}
}
4

2 に答える 2

1

私は手元にサムスンのデバイスを持っていません(Galaxy Nexusはカウントされません、それはプレーンなAndroidを持っており、あなたの例では非常にうまく機能します)ので、私の仮定をテストすることはできませんが、ListViewはそれの後にアイテムの選択された状態をドロップするようですリリースされました。HierarchyViewerで確認できます(電話がルート化されていない場合は、Romain GuyのViewServerを使用してください)。

TouchModeのため、タッチスクリーンを備えた選択に依存することは危険です(http://android-developers.blogspot.ru/2008/12/touch-mode.htmlを参照)。つまり、ユーザーがタッチスクリーンを操作しているときの選択(またはフォーカス)の概念はありません。エミュレータには通常十字キーが付いているため、動作が少し異なる場合があります。

したがって、のstate_checked代わりにを使用することをお勧めしますstate_selected。Androidには、役立つ可能性のあるCheckedTextViewがあります。ListViewを呼び出すだけsetItemCheckedです。このソリューションには、構成の変更間でチェックされたアイテムの位置を維持し、他のアイテムが押されたときに以前にチェックされたアイテムのチェックを自動的に解除するという優れた特性もあります(CHOICE_MODE_SINGLE使用されている場合)。

それが受け入れられず、固執する必要があるstate_selected場合は、TextViewをLinearLayoutにラップすることができます。これにより、選択が消えないようにする必要があります。ただし、ListViewは、画面が表示されなくなったときに他のリストアイテムに同じビューを再利用することを忘れないでください。そのため、適切に設定するには、アダプターで選択状態を追跡する必要があります。

于 2013-01-10T16:16:25.217 に答える
0

確認できますが、Samsungデバイス(Nexus、S3、Note2)でのみ同様のバグが発生しました。Listviewアイテムにはデフォルトの背景色があるため、私の場合は黒です。しかし、ランダムに赤くなります。listviewitem backgroundcolorを明示的に黒に設定した場合、バグは発生しません。正直なところ、私はあなたの場合の回避方法を知りませんが、すべての状態の色を定義することはあなたを助けるかもしれません。

于 2013-01-10T15:46:47.967 に答える