Android的ListView的选择问题问题、Android、ListView

2023-09-04 04:09:33 作者:心硪進不去ワ

大家好,

我以下长的问题道歉......

I apologize for the following long question...

我有一个LinearLayout中,其中包含一个ListView和其他一些物品。至于在ListView,每个在其行是包含3意见的LinearLayout - 复选框,ImageView的和TextView的(从左至右 - 水平)。 因为我想整行使用轨迹球(与背景色高亮显示)时,可以选择,我设置的LinearLayout行作为不可作为焦点,里面的三个观点,和它的工作。

I have a LinearLayout which contains a ListView and some other items. As for the ListView, each on of its rows is a LinearLayout that contains 3 views - Checkbox, ImageView and TextView (from left to right - horizontal). Since I wanted the whole row to be selected when using the trackball (to be highlighted with a background color), I set the all three views inside the LinearLayout row as not focusable, and it worked.

现在我有这方面的ListView 2个问题。 首先,我想,每当我在ListView触摸行(用手指),以获得相同的行为采用了轨迹球的时候 - 意味着我想要的行被选中(高亮)。这是怎么回事,现在是,当我触摸排它真的成为选择的,但是当我松开我的手指在选择了(就像发生在设备的联系人列表)。

Now I'm having 2 problems regarding this ListView. First, I want that whenever I touch a row in the ListView (with my finger), to get the same behavior as when using the trackball - means that I want the row to be selected (highlighted). What's happening right now is that when I touch the row it really becomes selected, but when I release my finger the selection is gone (much like happens in device's contact list).

二 - 从菜单中,我可以显示一个新的LinearLayout,而不是包含在ListView(不同应用程序的屏幕)之一。发生这种情况时,我还存储了包含在ListView中的LinearLayout的对象,因为我希望能够在以后重新显示它没有从头创建它。 问题是,当我重​​新disaply中的LinearLayout与ListView,没有ListView的行被选中,即使ceratin行被选中当了的LinearLayout与ListView左屏幕。

Second - from a Menu, I can display a new LinearLayout instead the one that contains the ListView (different application's screen). When this happens, I still stores the object of the LinearLayout that contains the ListView, because I want to be able to re-display it later without creating it from scratch. The problem is that when I re-disaply the LinearLayout with the ListView, none of the ListView's rows are selected, even if a ceratin row was selected when the the LinearLayout with the ListView "left" the screen.

再次对不起,长的帖子。

Sorry again for the long post.

谢谢!

推荐答案

是啊,从iOS开发者的角度来看,我觉得这是非常难以适用相同的特征设置默认选择启动时和记得选择状态后,用户点击行到ListView控件。

Yeah, From an iOS developer's perspective, I find that it is extremely hard to apply features like "set default selection when starting" and "remember selection status after user clicked row" to ListView.

因此​​,让我们开始的记得选择第一。问题是,即使你知道, 您可以选择使用XML来定义高光/ pressed /对焦style.But这种风格不会 保存后,用户点击该行。举例来说,我有一个高亮选择XML(list_selector.xml下RES /绘制文件夹)这样的(但你可能有其他领域需要突出像TextView中的行文本颜色):

So let's start with "remember selection" first.The problem is that even if you know that you can use selector xml to define highlight/pressed/focus style.But that style will not be kept after user clicked that row. For instance, I have a highlighting selector xml (list_selector.xml under res/drawable folder) like this (but you may have other fields need to highlight like text color of textview in row):

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

和它定义的高亮风格list_selector_ pressed.xml - 设置背景颜色 以灰色:

and list_selector_pressed.xml which defined the highlighting style--set the background color to a gray color :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <solid android:color="@color/dark_gray" />
        </shape>
    </item>
</layer-list>

因此​​,作为@大卫Hedlund的建议:

So as @David Hedlund suggested:

相反,分配OnItemClickListener,并将其所选项目的ID存储掳到一些变量。

Rather, assign an OnItemClickListener, and have it store away the id of the selected item into some variable.

您需要在您的类的顶部创建一个实例变量:

you need to create a instance variable on top of your class:

    private View currentSelectedView;

然后到

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    if (currentSelectedView != null && currentSelectedView != v) {
        unhighlightCurrentRow(currentSelectedView);
    }

    currentSelectedView = v;
    highlightCurrentRow(currentSelectedView);
    //other codes 
    }

pretty的简单:我们是否currentSelectedView为空或电流点击查看与否。我们首先通过调用方法unhighlightCurrentRow(currentSelectedView)unhighlight任何风格---你可能想知道为什么我们通过即时可变currentSelectedView为参数,我稍后会解释它。然后我们分配以currentSelectedView并强调当前行;这样的风格会持续之后,用户的点击完成。

Pretty simple: we check if currentSelectedView is null or current clicked view or not. we first to unhighlight any style by calling method unhighlightCurrentRow(currentSelectedView)---you may wonder why we pass instant variable currentSelectedView as parameter, I will explain it later. Then we assign view to currentSelectedView and highlight current row; so that the style will persist after user's clicking is done.

private void unhighlightCurrentRow(View rowView) {
    rowView.setBackgroundColor(Color.TRANSPARENT);
    TextView textView = (TextView) rowView.findViewById(R.id.menuTitle);
    textView.setTextColor(getResources().getColor(R.color.white));
}

private void highlightCurrentRow(View rowView) {
    rowView.setBackgroundColor(getResources().getColor(
            R.color.dark_gray));
    TextView textView = (TextView) rowView.findViewById(R.id.menuTitle);
    textView.setTextColor(getResources().getColor(R.color.yellow));

} 

啊哈,仅此而已。这就是我们如何实现记住选择的列表视图。如你所见, 我们必须既在XML和Java code复制codeS的造型 - pretty的愚蠢:(

Aha, that's it. That is how we implement "remember selection" for list view. As you see, we have to duplicate the codes for styling both in xml and java code--pretty stupid :(

下一步关于设置默认选择。你可能会认为你可以做到这一点。

Next about "set default selection". You may think that you can do this

listView.setAdapter(adatper)
listView.setSelection(0);
currentSelectedView = listView.getChildAt(0);
highlightCurrentRow(currentSelectedView);

在的onCreate()在活动或onActivityCreated()的片段。 但是,如果你运行它,你会得到空指针异常,为什么? 因为在这个时候,列表视图不会呈现尚未和Android不喜欢具有viewWillAppear中的iOS。所以,你必须创建一个即时变量来记住它是否是第一次来呈现列表视图小区和onListItemClick来取消该变量:

in onCreate() in activity or onActivityCreated() in fragment. But if you run it , you will get NullPointer exception and why ? because at this time, the listview is not rendered yet and Android doesn't like iOS which have viewWillAppear. SO you have to create an instant variable to remember whether it is first time to render listview cell and in onListItemClick to unset that variable:

所以在currentSelectedView声明:

So under currentSelectedView declaration:

private Boolean firstTimeStartup = true;

再添加方法:假设我们想强调在列表视图中的第一行:

then add methods : suppose we want to highlight the first row in list view:

public class HomeAdapter extends ArrayAdapter<String> {
    int layoutResourceId;

    public HomeAdapter(Context context, int textViewResourceId,
            ArrayList<String> objects) {
        super(context, textViewResourceId, objects);
        layoutResourceId = textViewResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(
                    layoutResourceId, null);
        }

        if (firstTimeStartup && postion == 0) {
            highlightCurrentRow(convertView);
        } else {
            unhighlightCurrentRow(convertView);
        }

        TextView title = (TextView) convertView
                .findViewById(R.id.menuTitle);
        title.setText(getItem(position));
        return convertView;
    }
}

pretty的简单。 但是,你需要在onListItemClick方法的一些变化:

Pretty simple. But you need to make some changes in onListItemClick method:

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

    if (firstTimeStartup) {// first time  highlight first row
        currentSelectedView = l.getChildAt(0);
    }
    firstTimeStartup = false; 
    if (currentSelectedView != null && currentSelectedView != v) {
        unhighlightCurrentRow(currentSelectedView);
    }

    currentSelectedView = v;
    highlightCurrentRow(currentSelectedView);

     //other codes
}

你去那里!享受Android的:)

There you go! Enjoy Android :)

 
精彩推荐
图片推荐