我怎样才能改变背景色的特定行适当在ListView? (安卓) [英] How can I change the background color for an specific row properly in a ListView? (Android)

查看:184
本文介绍了我怎样才能改变背景色的特定行适当在ListView? (安卓)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了几天试图解决一个问题,我与在Android列表视图。我想实现用一个ListView单一选择列表框。所以,我想只有一个用predefined浅背景颜色,其余的与另一preselected色行。我的问题是,当我点击了一个特定的行是另一行被突出显示,没有一个我pressed。我加了一些消息日志发生了什么,但一切似乎很好地工作。这是我的code:

I have spent some days trying to solve a problem I have with ListViews on Android. I would like to implement a single selection list box using a ListView. So, I would like to have only one row with a predefined light background color and the rest with another preselected color. The problem I have is that when I click over a specific row is another row which is highlighted and not the one I pressed. I added several messages to Log what is happening but all seems to work fine. Here is my code:

public class TryListViewActivity extends Activity {
    protected static final int NO_SELECTED_COLOR = 0xFF191919;
    protected static final int SELECTED_COLOR = 0xFF3366CC;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ListView listView = new ListView(this);
        ArrayList<String> list = new ArrayList<String>();
        list.add("Option 1");
        list.add("Option 2");
        list.add("Option 3");
        list.add("Option 4");
        list.add("Option 5");
        list.add("Option 6");
        list.add("Option 7");
        list.add("Option 8");
        list.add("Option 9");
        list.add("Option 10");
        list.add("Option 11");
        list.add("Option 12");
        list.add("Option 13");
        list.add("Option 14");
        list.add("Option 15");

        ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(
            this,
            R.layout.list_box_entry,
            list
        );
        listView.setAdapter(listAdapter);

        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        // Set the listener
        listView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                    Log.i(
                        "Log",
                        "[SingleSelectionListBox] Item clicked: position="
                        + position + ";id=" + id
                    );

                    // First, set all rows to be unselected
                    int counter  = parent.getCount();
                    Log.i(
                        "Log",
                        "[SingleSelectionListBox] "
                        + counter + " items found inside the parent"
                    );
                    int children = parent.getChildCount();
                    Log.i(
                        "Log",
                        "[SingleSelectionListBox] "
                        + children + " views found inside the parent"
                    );
                    for(int i=0;i<children;i++) {
                        Log.i(
                            "Log",
                            "[SingleSelectionListBox] Child "
                            + i + " has message "
                            + ((TextView)parent.getChildAt(i)).getText()
                        );
                    }

                    // Too inefficient but for now is OK
                    for(int i=0;i<children;i++)
                        parent.getChildAt(i)
                            .setBackgroundColor(NO_SELECTED_COLOR);
                    Log.i("Log",
                        "[SingleSelectionListBox] First visible position: "
                        + parent.getFirstVisiblePosition()
                    );

                    // Set the background color
                    TextView textView = (TextView)(parent.getChildAt(
                        position-parent.getFirstVisiblePosition()));
                    textView.setBackgroundColor(SELECTED_COLOR);
                    Log.i(
                        "Log",
                        "[SingleSelectionListBox] Text inside the "
                        + " View changing the color " + textView.getText()
                    );
                }
            }
        );
        setContentView(listView);
    }
}

里面的资源(RES /布局)我插入了一个名为list_text_entry.xml包含以下内容的文件

Inside the resources (res/layout) I inserted a file called list_text_entry.xml with the following content

<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:gravity="center"
  android:textColor="#FFFFFF" android:padding="10dp" android:textSize="16sp">
</TextView>

例如,如果我点击在选项11项时,在ListView已经previously向下滚动,直到我看到的第一行是选项4,作为选定作为的选项7出现一行只有一个背着一个蓝色的背景。有人能解释发生了什么我这里来?我后下我扔日志的消息。

For example, If I click over the "Option 11" entry when the listView has been previously scrolled down until the first row I see is "Option 4", the "Option 7" row appears as selected being the only one carrying a blue color in the background. Can someone explain what happens here to me? I post below the messages I got throw the Log.

[SingleSelectionListBox] Item clicked: position=10;id=10
[SingleSelectionListBox] 15 items found inside the parent
[SingleSelectionListBox] 11 views found inside the parent
[SingleSelectionListBox] Child 0 has message Option 4
[SingleSelectionListBox] Child 1 has message Option 5
[SingleSelectionListBox] Child 2 has message Option 6
[SingleSelectionListBox] Child 3 has message Option 7
[SingleSelectionListBox] Child 4 has message Option 8
[SingleSelectionListBox] Child 5 has message Option 9
[SingleSelectionListBox] Child 6 has message Option 10
[SingleSelectionListBox] Child 7 has message Option 11
[SingleSelectionListBox] Child 8 has message Option 12
[SingleSelectionListBox] Child 9 has message Option 13
[SingleSelectionListBox] Child 10 has message Option 14
[SingleSelectionListBox] First visible position: 3
[SingleSelectionListBox] Text inside the View changing the color Option 11

据我可以猜对的ViewGroup内的所有儿童责令从上到下,甚至当我做到这一点,在code:

As I can guess all children inside the ViewGroup as ordered from top to bottom and even when I do this in the code:

TextView textView = (TextView)(parent.getChildAt(
    position-parent.getFirstVisiblePosition()
));
textView.setBackgroundColor(SELECTED_COLOR);

会出现信息选项11 ,但真的是选项7 选择。这是Android的一个bug?

Appears the message Option 11 but is really the option 7 selected. Is this a bug from Android?

推荐答案

感谢戴夫和ChristianB你的答案。我仍然不知道为什么Android的做吧,这样的问题仍然没有得到解决。然而,我发现了一个方式来获得我所需要创建一个自定义的适配器。我会给你code,以防有人可能会需要它。

Thanks Dave and ChristianB for your answers. I still do not know why Android does it, so the question is still unresolved. However, I found a way to get what I needed creating a custom Adapter. I will give you the code in case someone could need it.

public class CustomAdapter extends ArrayAdapter<String> {

    protected static final int NO_SELECTED_COLOR = 0xFF191919;
    protected static final int SELECTED_COLOR = 0xFF3366CC;

    private ArrayList<String> items;
    private LayoutInflater mInflater;
    private int viewResourceId;
    private int selectedPosition;

    public CustomAdapter(Activity activity,int resourceId,
        ArrayList<String> list) {
        super(activity,resourceId,list);

        // Sets the layout inflater
        mInflater = (LayoutInflater)activity
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // Set a copy of the layout to inflate
        viewResourceId = resourceId;

        // Set a copy of the list
        items = list;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView tv = (TextView)convertView;
        if (tv == null) {
            tv = (TextView)mInflater.inflate(viewResourceId, null);
        }
        tv.setText(items.get(position));

        // Change the background color
        if (position==selectedPosition) tv.setBackgroundColor(SELECTED_COLOR);
        else tv.setBackgroundColor(NO_SELECTED_COLOR);

        return tv;
    }

    public void setSelected(int position) {
        selectedPosition = position;
    }
}

所以,在ListView初始化我只是需要把这个监听器:

So, in the ListView initialization I just need to put this listener:

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

这是不是因为我是从ArrayAdapter这是假设已经提供了所有数据的副本扩展的高效解决方案。因此,我现在用的比需要更多的内存和案例列表变得非常大,我可以有记忆的麻烦。所以,如果有人知道一个更好的解决方案,请邮寄!

This is not an efficient solution due to I am extending from ArrayAdapter which is suppose to have a copy of all data provided. Thus, I am using much more memory than needed and in case the list becomes very large I could have memory trouble. So, if someone knows a better solution, please post!

这篇关于我怎样才能改变背景色的特定行适当在ListView? (安卓)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆