更改 ListView 背景 - 奇怪的行为 [英] Change ListView background - strange behaviour

查看:19
本文介绍了更改 ListView 背景 - 奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在更改 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() 这样做,这就是为什么我不明白为什么它实际上也发生在其他条目上.我注意到的一件事是:它似乎只是绘图"部分,因为自己"选择的项目仍然具有 selectedfalse

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屋!

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