更改ListView背景 - 奇怪的行为

时间:2011-01-03 09:26:44

标签: java android listview onclick background-image

我在更改ListView中视图的背景时遇到问题。

我需要什么:
更改onClick()

上一行的背景图片

实际发生的事情:
在按下例如后,背景被改变(选择)第一个条目。但在向下滚动后,也会选择第8个条目。 滚动回到顶部,第一个不再被选中。现在选择第二个条目。 继续滚动,继续跳...

我在守则中的内容:
我有频道和onClick()我切换频道布尔选择的属性 然后我改变了背景。 我正在做 onClick()这就是为什么我不明白为什么它也会在其他条目上发生。 我注意到的一件事是:它似乎只是“绘图” - 部分,因为“通过它自己”选择的项目在错误 <上仍然具有选定的值/ p>

我认为这似乎与自定义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;
}

我真的很感激任何想法如何解决这个问题! :)

如果需要更多信息,请告诉我。

提前致谢!

1 个答案:

答案 0 :(得分:10)

让我向您展示我为每个ListView使用的代码,并正确控制click事件以更改背景并进行更多操作

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

}

officelistitemlayout.xml文件将如下所示添加drawable并根据您在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>

希望它会有所帮助:)