如何在Android中ListView中突出显示行?
我需要突出显示选中的ListView
中的一行(向用户显示他select的内容),因此,不是要select的那个,而是他之前select的那个。
我已经有了位置:
ListView.setSelection(position);
而现在我想要的是select这个特定的行,并突出显示它。
包含ListView
的活动中onCreate()
的代码:
public class CountryView extends Activity { protected static final String LOG_TAG = null; /** Called when the activity is first created. */ String[] lv_arr = {}; ListAdapter adapter; TextView t; private ListView lvUsers; private ArrayList<Coun> mListUsers; String responce=null; public int d; int selectedListItem = -1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.country); Intent data =getIntent(); mListUsers = getCoun(); lvUsers = (ListView) findViewById(R.id.counlistView); lvUsers.setAdapter(new ListAdapter(this, R.id.counlistView, mListUsers)); selectedListItem=data.getExtras().getInt("PositionInList"); lvUsers.setChoiceMode(ListView.CHOICE_MODE_SINGLE); lvUsers.setOnItemClickListener(new OnItemClickListener() { int positionItem; public void onItemClick(AdapterView<?> parent, View view,int position, long id) { Intent pongIntent = new Intent(getApplicationContext(),Trav.class); int counId=mListUsers.get(position).id; pongIntent.putExtra("response",mListUsers.get(position).p); pongIntent.putExtra("responseCounID",counId); //Put the position of the choose list inside extra positionItem=position; pongIntent.putExtra("PositionInListSet",positionItem); setResult(Activity.RESULT_OK,pongIntent); Log.i("CounID *******************************"," "+counId); finish(); } }); } }
由于默认ListViews
被设置为NONE
的select模式,在触摸模式下, setSelection
方法将不具有视觉效果。
为了保持以前的select/直观显示一个明确的select,首先你必须适当地设置你的列表视图的select模式:
listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
阅读这些方法的API文档是有用的:
- 为setSelection
void android.widget.AdapterView.setSelection(int position)
设置当前select的项目。 要支持覆盖此方法的辅助function子类,必须首先调用overriden超级方法。
参数 :
要select的数据项的position
索引(从0开始)。
- setChoiceMode
void android.widget.ListView.setChoiceMode(int choiceMode)
定义列表的select行为。 默认情况下,列表没有任何select行为(
CHOICE_MODE_NONE
)。 通过将choiceMode设置为CHOICE_MODE_SINGLE
,List允许最多一个项目处于选定状态。 通过将choiceMode设置为CHOICE_MODE_MULTIPLE
,该列表允许select任意数量的项目。参数 :
choiceMode
CHOICE_MODE_NONE
,CHOICE_MODE_SINGLE
或CHOICE_MODE_MULTIPLE
如果这还不够(比如你希望总是在当前select旁显示最后一个select),则应该将上一次select的项目(填充ListAdapter
的数据)存储为lastSelectedItem
,并将其存储在适配器的getView
方法中如果渲染器等于lastSelectedItem
渲染器提供不同的背景资源。
如果最后一个select不会在select更改时刷新,则应该在适配器实例上显式调用notifyDataSetChanged
方法。
更新
由于包含ListView
的活动是等待这个结果的setResult(Activity.RESULT_OK,pongIntent);
(基于setResult(Activity.RESULT_OK,pongIntent);
part),所以最初的想法是正确的,最后一个位置应该通过intent传递开始活动:
selectedListItem = getIntent().getIntExtra("PositionInList", -1); lvUsers.setChoiceMode(ListView.CHOICE_MODE_SINGLE); lvUsers.setSelection(selectedListItem);
ListView.CHOICE_MODE_SINGLE
解决scheme将工作,如果你仍然在同一个活动,但你正在完成每一个itemClick(select变化),这就是为什么额外的数据应该传递到开始Intent
。
您也可以从您的适配器设置之前select的项目背景(如上所述),覆盖其getView
方法:
lvUsers.setAdapter(new ArrayAdapter(this, R.id.counlistView, groups) { @Override public View getView(int position, View convertView, ViewGroup parent) { final View renderer = super.getView(position, convertView, parent); if (position == selectedListItem) { //TODO: set the proper selection color here: renderer.setBackgroundResource(android.R.color.darker_gray); } return renderer; } });
只是:
- 在列表视图中设置正确的select模式。
setChoiceMode
-
设置背景以支持项目布局中的select状态,如:
android:background="?android:attr/activatedBackgroundIndicator"
供参考:
在你的布局文件中实现这个要容易得多,让Android处理剩下的事情。
1)确保你的ListView布局 ( singleChoice
, multipleChoice
等)上设置了android:choiceMode=""
。 默认情况下它被设置为none
。
<ListView android:id="@+id/invite_friends_fragment_contacts_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:choiceMode="multipleChoice"/> <!-- THIS LINE -->
2)创build一个状态select器XML文件,并将其保存在drawables文件夹中。 在这个例子中,我们将其命名为state_selector.xml :
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/blue" android:state_selected="true"/> <item android:drawable="@android:color/blue" android:state_activated="true"/> <item android:drawable="@android:color/transparent"/> </selector>
3)在列表项目布局中 ,添加state_selector.xml文件作为背景:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/state_selector"> <!-- THIS LINE --> <!-- ALL OF YOUR ELEMENTS WILL GO HERE (TextViews, ImageViews, etc) --> </RelativeLayout>
如果您正在使用multipleChoice
,则可以覆盖onItemClick()
并相应地设置/取消设置所选项目 。 Android会根据您的state_selector.xml文件中的指定更改背景颜色。
我遇到了一个问题find一个简单的解决scheme,因为这么多的教程和答案包含单选button(其中很大程度上依赖RadioGroup的)单选的信息。
我的问题是我可以将项目设置为我的“突出显示”状态,但是当下一个项目被选中时无法重置列表。 这是我想出来的:
listView.setOnItemClickListener(new ItemHighlighterListener ());
有了这门课:
private class ItemHighlighterListener implements OnItemClickListener{ private View lastSelectedView = null; public void clearSelection() { if(lastSelectedView != null) lastSelectedView.setBackgroundColor(android.R.color.transparent); } @Override public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) { clearSelection(); lastSelectedView = view; view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.shape_selected_menu_item)); } }
我用下面的方法来解决这个问题:1.设置lastClickId,当点击listView中的项时,更新lastClickId到position的值,然后更新视图的背景。 在这之后,当我们点击一个项目时,这个项目会被高亮显示,但是当我们滚动listView(使得我们从屏幕中select的项目)并向回滚动时,高亮度消失了,因为getView()方法重新运行你的适配器,所以,我们必须做下一件事。 2.在你的适配器中,改变方法getView()的背景,这里是代码:
private static int lastClickId = -1; private OnItemClickListener listener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if ((lastClickId != -1) && (lastClickId != position)) { parent.getChildAt(lastClickId).setBackgroundResource( R.color.grey); view.setBackgroundResource(R.color.blue); } if (lastClickId == -1) { view.setBackgroundResource(R.color.blue); } lastClickId = position; } }; public static int getCurrentSelectedItemId() { return lastClickId; }
适配器:
public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View view = mInflater.inflate(R.layout.tweet_list_layout, null); // set selected item's background to blue if (position == MainUserFeedFragment.getCurrentSelectedItemId()) { view.setBackgroundResource(R.color.blue); } }
为什么不把select存储在数组中,然后将这个数组传递给ListView Array Adapter的构造函数,就像myArrayAdapter(context,layoutID,dataArray,selectionArray)
然后在arrayAdapter的getView
方法中,只需进行检查即可。 例如在伪代码中
if row was previously selected change background color
你可以使用转换。 按照我的代码,因为我已经实现了特定列表视图项目的突出显示让我们说你想突出显示第一个项目5秒。
if(position == 0){ viewHolderThubnail.relImage.setBackgroundResource(R.drawable.translate); TransitionDrawable transition = (TransitionDrawable) viewHolderThubnail.relImage.getBackground(); transition.startTransition(1000); }else{ viewHolderThubnail.relImage.setBackgroundResource(R.color.white); }
translate.xml
<?xml version="1.0" encoding="UTF-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <!-- The drawables used here can be solid colors, gradients, shapes, images, etc. --> <item android:drawable="@drawable/new_state" /> <item android:drawable="@drawable/original_state" /> </transition>
new_state.xml
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#92BCE7"/> </shape>
original_state.xml
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#FFFFFF"/> </shape>
如果你理解了这个代码,这是非常简单的,我必须说,那么位于第零的位置的listview项目会以蓝色高亮显示5秒钟,然后会慢慢地淡化为白色。
最简单的closures所有
查看updatedview = null;
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //these two lines of code means that only one item can be selected at a time if(updatedview != null) updatedview.setBackgroundColor(Color.TRANSPARENT); updatedview=view; Toast.makeText(getApplicationContext(), " " + str[position], Toast.LENGTH_LONG).show(); view.setBackgroundColor(Color.CYAN); }