更改 ListView 背景 - 奇怪的行为 [英] Change ListView background - strange behaviour
问题描述
我在更改 ListView 中的视图背景时遇到问题.
I have a problem with changing the background of a view in a ListView.
我需要什么:
改变一行的背景图片 onClick()
What I need:
Change the background image of a row onClick()
实际情况:
按下后背景会改变(选择),例如第一个条目.但是向下滚动后,第 8 个条目也被选中.滚动回到顶部,第一个不再被选中.现在选择了第二个条目.继续滚动,它继续跳跃...
What actually happens:
The background gets changed (selected) after pressing e.g. the first entry. But after scrolling down the 8th entry is selected too.
Scroll back to the top the first isn't selected anymore. The second entry is selected now.
Continue scrolling and it continues jumping...
代码中的我是什么:
我有频道,并且 onClick() 我切换了频道 boolean selected 的属性然后我改变了背景.我正在只 onClick() 这样做,这就是为什么我不明白为什么它实际上也发生在其他条目上.我注意到的一件事是:它似乎只是绘图"部分,因为自己"选择的项目仍然具有 selected 值 false
What i'm dong in the Code:
I have channels, and onClick() I toggle an attribute of channel boolean selected
and then I change the background.
I'm doing this only onClick() thats why I don't get why it's actuelly happening on other entries too.
One thing I notices is: It seems to be only the "drawing"-part because the item which get selected "by it self" has still the selected value on false
我认为这似乎与自定义 ListAdapters getView(...) 中视图的重用有关
I think it seems to have something to do with the reuse of the views in the custom ListAdapters getView(...)
ListActivity 中 onClick() 的代码:
@Override
protected ViewHolder createHolder(View v) {
// createHolder will be called only as long, as the ListView is not
// filled
TextView title = (TextView) v
.findViewById(R.id.tv_title_channel_list_adapter);
TextView content = (TextView) v
.findViewById(R.id.tv_content_channel_list_adapter);
ImageView icon = (ImageView) v
.findViewById(R.id.icon_channel_list_adapter);
if (title == null || content == null || icon == null) {
Log.e("ERROR on findViewById",
"Couldn't find Title, Content or Icon");
}
ViewHolder mvh = new MyViewHolder(title, content, icon);
// We make the views become clickable
// so, it is not necessary to use the android:clickable attribute in
// XML
v.setOnClickListener(new ChannelListAdapter.OnClickListener(mvh) {
public void onClick(View v, ViewHolder viewHolder) {
// we toggle the enabled state and also switch the the
// background
MyViewHolder mvh = (MyViewHolder) viewHolder;
Channel ch = (Channel) mvh.data;
ch.setSelected(!ch.getSelected()); // toggle
if (ch.getSelected()) {
v.setBackgroundResource(R.drawable.row_blue_selected);
} else {
v.setBackgroundResource(R.drawable.row_blue);
}
// TESTING
Log.d("onClick() Channel", "onClick() Channel: "
+ ch.getTitle() + " selected: " + ch.getSelected());
}
});
return mvh;
}
getView(...) 的代码:
@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
// When view is not null, we can reuse it directly, there is no need
// to reinflate it.
// We only inflate a new View when the view supplied by ListView is
// null.
if (view == null) {
view = mInflater.inflate(mViewId, null);
// call own implementation
holder = createHolder(view);
// TEST
// we set the holder as tag
view.setTag(holder);
} else {
// get holder back...much faster than inflate
holder = (ViewHolder) view.getTag();
}
// we must update the object's reference
holder.data = getItem(position);
// <EDIT SOLUTION>
if(getItem(position).get_id() == channelList.get(position).get_id()){
if(getItem(position).getSelected())
{
view.setBackgroundResource(R.drawable.row_blue_selected);
}
else{
view.setBackgroundResource(R.drawable.row_blue);
}
}
// </EDIT SOLUTION>
// call the own implementation
bindHolder(holder);
return view;
}
我真的很想知道如何解决这个问题!:)
I really would appreciate any idea how to solve this! :)
如果需要更多信息,请告诉我.
If more information is needed please tell me.
提前致谢!
推荐答案
让我向您展示我用于每个 ListView
的代码,并正确控制单击事件以更改背景并执行任何进一步操作
Let me show you the code that I use for every ListView
and properly controlling the click event for changing the background and doing anything further
public class Offices extends Activity {
private ListView listView;
/* selectedListItem will contain the number of items to be selected.
* Your list item OnOlickListener will simply change this variable
* to the position of the clicked item. The Adapter will do the rest
* because you need to refresh the ListView.
*/
private int selectedListItem = -1;
private Handler mHandler = new Handler();
private Vector<String> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.officeslayout);
data = new Vector<String>();
// Add data as per your requirement
data.add("one");
data.add("two");
data.add("three");
data.add("four");
data.add("Five");
data.add("Six");
data.add("Seven");
data.add("Eight");
data.add("Nine");
data.add("Ten");
listView = (ListView)findViewById(R.id.ListView01);
listView.setDivider(null);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
selectedListItem = position;
((EfficientAdapter)listView.getAdapter()).notifyDataSetChanged();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// call any new activity here or do any thing you want here
}
}, 200L);
}
});
listView.setAdapter(new EfficientAdapter(getApplicationContext()));
}
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = mInflater.inflate(R.layout.officeslistitemlayout, null);
holder = new ViewHolder();
holder.backgroundView = (ImageView) convertView
.findViewById(R.id.OfficesBackground);
holder.officesTitle = (TextView) convertView
.findViewById(R.id.OfficesName);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(position == selectedListItem) {
holder.backgroundView.setBackgroundResource(R.drawable.and_gray_bg_listing_selected);
} else {
holder.backgroundView.setBackgroundResource(R.drawable.and_gray_bg_listing);
}
holder.officesTitle.setText(data.get(position));
return convertView;
}
}
static class ViewHolder {
TextView officesTitle;
ImageView backgroundView;
}
}
<小时>
officeslistitemlayout.xml 文件会像下面一样添加drawable并根据你在RelativeLayout中放置以下代码进行设计
officeslistitemlayout.xml file will be like following add drawable and design it according to you put the following code in RelativeLayout
<ImageView android:id="@+id/OfficesBackground" android:layout_width="fill_parent"
android:layout_height="45dip"
android:layout_alignParentTop="true"
android:background="@drawable/and_gray_bg_listing"
android:scaleType="fitXY"
></ImageView>
<TextView android:id="@+id/OfficesName" android:layout_width="wrap_content"
android:text="Offices Name"
android:textColor="#000000" android:textStyle="bold"
android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_marginLeft="5dip"
></TextView>
希望它会有所帮助:)
这篇关于更改 ListView 背景 - 奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!