ListView的回收方式如何运作

时间:2014-09-03 20:15:58

标签: android android-layout

我的项目中有一个listView,我希望在单击listItem时更改背景颜色。但是当我点击一行时,它会改变许多行。

以下是此功能的代码:

 public View getView(int pos, View view, ViewGroup parent) {
        mActivity = (Activity) this.getContext();
        ListViewHolder holder;


        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.portfolio_row, null);

            LinearLayout textViewWrap = (LinearLayout) view.findViewById(R.id.portfolio_text_wrap);
            TextView text = (TextView) view.findViewById(R.id.portfolio_symbol);
            holder = new ListViewHolder(textViewWrap, text);

        } else
            holder = (ListViewHolder) view.getTag();





        PortfolioItem portfolioItem = getItem(pos);
}

但是当我点击一行时,它会改变许多行。

我为pos获得了system.out.println。我应该得到它应该是0 1 2 3 4 5 6 7 8 9(#代表位置)。我得到的是一个像这样的循环:0 1 2 3 0 1 2 3 0 1

因此,如果我点击一个,它将改变所有相同的位置。 但是如果我没有点击,只需将listView拉下来,位置就是正确的。就像0 ---- 9。

以下是项目点击的代码:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        list = (ListView) root.findViewById(R.id.~~~);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parentAdapter, View view, int position, long id) {

                toggle(view, position);
            }
        });
}

我想要的是在listView中获取它的绝对位置。 请帮帮我。谢谢!

更新: 感谢大家的善意回答。但我想你可能会误解我的问题。

  1. getView更改位置。这意味着当你想要更改第9行时,它无法更改,因为我只有0 1 2 3

  2. getView()和onCreateView()属于不同的类。 System.out.println(“pos”+ pos);在getView中无法获得正确的位置。

    正确的方法应该是1到最后一项。但是当我点击它时,数字将是一个循环。循环数是屏幕可以显示的行数。

  3. 就像这个链接How ListView's recycling mechanism works

    我想点击只获得一个正确的位置。非常感谢。

    这是layout.xml:

     <LinearLayout a:orientation="vertical"
                      a:layout_width="fill_parent"
                      a:layout_height="fill_parent">
    
            <LinearLayout a:orientation="horizontal" a:layout_width="fill_parent" a:layout_height="wrap_content"
                          a:background="@color/onSelected">
                <TextView a:text="@string/1" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:layout_margin="10dp" a:textStyle="bold" a:id="@+id/0"/>
                <TextView a:text="@string/2" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:gravity="right" a:layout_margin="10dp" a:textStyle="bold"/>
                <TextView a:text="@string/3" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:gravity="right" a:layout_margin="10dp" a:textStyle="bold"/>
                <TextView a:text="@string/4" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:gravity="right" a:layout_margin="10dp" a:textStyle="bold"/>
                <TextView a:text="@string/5" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:gravity="right" a:layout_margin="10dp" a:textStyle="bold"/>
                <TextView a:text="@string/6" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:gravity="right" a:layout_margin="10dp" a:textStyle="bold"/>
                <TextView a:text="@string/7" a:layout_weight="1" a:layout_width="fill_parent"
                          a:layout_height="fill_parent" a:gravity="right" a:layout_margin="10dp" a:textStyle="bold"/>
            </LinearLayout>
            <android.support.v4.widget.SwipeRefreshLayout a:layout_width="fill_parent"
                                                          a:layout_height="fill_parent"
                                                          a:id="@+id/portfolios">
                <ListView a:layout_width="fill_parent" a:layout_height="fill_parent" a:id="@+id/8" />
            </android.support.v4.widget.SwipeRefreshLayout>
        </LinearLayout>
    

    UPDATES2: 这是listViewHolder:

    public class ListViewHolder {
        private LinearLayout textViewWrap;
        private TextView textView;
    
    
        public ListViewHolder(LinearLayout textViewWrap, TextView textView) {
            super();
            this.textViewWrap = textViewWrap;
            this.textView = textView;
        }
    
        public TextView getTextView() {
            return textView;
        }
    
        public void setTextView(TextView textView) {
            this.textView = textView;
        }
    
        public LinearLayout getTextViewWrap() {
            return textViewWrap;
        }
    
        public void setTextViewWrap(LinearLayout textViewWrap) {
            this.textViewWrap = textViewWrap;
        }
    }
    

    这里设置片段

    class fragment{
    
            list = (ListView) root.findViewById(R.id.123);
            list.setAdapter(adapter);
    
    }
    

    在fragment类中我有listItemClickListener,在适配器中我有getView函数

3 个答案:

答案 0 :(得分:1)

我有一个想法,是否可以使用

    final int firstListItemPosition = ((ListView) parent).getFirstVisiblePosition();
    final int lastListItemPosition = ((ListView) parent).getLastVisiblePosition();

两个函数来计算正确的位置。任何人都可以做到吗?

Android滚动功能可以获得正确的位置信息吗?任何人都可以解释它是如何工作的?

这个http://android.amberfog.com/?p=296给出了滚动工作的示例。但是当点击一行做加法功能时,效果不好。

我认为解决此问题的另一种方法是使用bindview更新视图使用hashmap来存储ID信息,如果ID存在,则更改具有相同ID的其他行。如果再次单击该行,请从散列映射中删除ID

答案 1 :(得分:1)

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parentAdapter, View view, int position, long id) {
                adapter.changeVisable(view, position);   


public void changeVisable(View view, int position) {
        if (mLastView != null && mLastPosition != position) {
            ListViewHolder holder = (ListViewHolder) mLastView.getTag();
            switch (holder.getTxt().getVisibility()) {
                case View.VISIBLE:
                    holder.getTxt().setVisibility(View.GONE);
                    mLastVisibility = View.GONE;
                    break;
                default:
                    break;
            }
        }
        mLastPosition = position;
        mLastView = view;
        ListViewHolder holder = (ListViewHolder) view.getTag();
        switch (holder.getTxt().getVisibility()) {
            case View.GONE:
                holder.getTxt().setVisibility(View.VISIBLE);
                mLastVisibility = View.VISIBLE;
                break;
            case View.VISIBLE:
                holder.getTxt().setVisibility(View.GONE);
                mLastVisibility = View.GONE;
                break;
        }
    }

works perfect

答案 2 :(得分:0)

int selected;
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parentAdapter, View view, int position, long id) {
selected=position;
adapter.notifyDataSetChanged();
                toggle(view, position);
            }
        });
中的

public View getView(int pos, View view, ViewGroup parent) {
....
...
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.portfolio_row, null);
if(pos==selected){
view.setBackgroundResource("your color");
.....


}

你需要为每个视图设置标签,你错过了:

if (view == null) {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.portfolio_row, null);

            LinearLayout textViewWrap = (LinearLayout) view.findViewById(R.id.portfolio_text_wrap);
            TextView text = (TextView) view.findViewById(R.id.portfolio_symbol);
            holder = new ListViewHolder(textViewWrap, text);
view.setTag(holder);
        }