【问题标题】:ListView item state_selected is lost on real deviceListView 项目 state_selected 在真实设备上丢失
【发布时间】:2012-12-23 15:54:56
【问题描述】:

我对三星手机上的简单 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 的项目)使用 ColorStateList 作为 textColor(按下-->绿色;选中-->蓝色;默认-->红色)。

在模拟器上,一切都很好:默认情况下,项目是红色的,当我按下一个时它变成绿色,当我松开它时它变成蓝色。如果我选择另一个项目:之前选择的变回红色,新选择的变成蓝色。

在我的三星设备上:默认情况下,项目是红色的,当我按下一个时它变成绿色,当我松开它时它再次变成红色(即未选中)。

这似乎是三星 ListView 实现中的一个错误(这是一个自定义实现,如果没有源代码就很难追踪)。

编辑:不是错误,而是由于触摸模式而略有不同的行为(请参阅已接受答案中的链接)

您对如何解决此错误/行为有任何想法吗?

附加限制:我不能使用 xml 选择器,因为我收到的颜色只能在运行时使用。

我的设备是三星 GT-B5330,API 15。(但我预计大多数三星设备都会出现这种情况)

这是完整的(可编译的)代码

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;
    }
}
}

【问题讨论】:

  • GT-5330有硬件键盘吗?我发现 GT-B5330 有一个但没有关于你提到的 GT-5330 的信息。
  • 是的,它有一个硬件键盘,我编辑我的帖子以设置正确的参考。 (对不起)

标签: java android android-listview samsung-mobile


【解决方案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 在离开屏幕时会为其他列表项重用相同的视图,因此您需要跟踪适配器中的选择状态以正确设置它。

【讨论】:

  • 为这篇文章中的所有内容+1。使用 state_checked 效果很好。所有参考资料都非常有用。非常感谢。
【解决方案2】:

我可以确认,我只在三星设备(Nexus、S3、Note2)上遇到过类似的错误。 Listview 项目具有默认背景颜色,因此在我的情况下为黑色。但随机它变成红色。如果我将 listviewitem backgroundcolor 显式设置为黑色,则不会遇到该错误。老实说,我不知道如何解决您的情况,但定义所有状态的颜色可能会对您有所帮助。

【讨论】:

    猜你喜欢
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多