0

我想更新我的按钮ListView。我目前拥有的代码工作正常,但有一个小故障,当到达最后一项时,它会突然用上一篇文章中的错误数据更新第一项,因为它是最后一篇文章。我不知道会发生什么,在我的日志我没有得到任何表明第一项正在更新的信息。我从这个类似的问题中得到了这个代码和想法。

这是我使用的代码:

/**
     * Updates the like/dislike button states 
     */
    public void updateButtons() {
        ListView lv = ((ListView) findViewById(R.id.post_list));
        Log.d("Child Count: ", Integer.toString(lv.getCount()));
        int firstVisible;
        int child;
        for(int i=0; i < lv.getCount(); i++) {
            firstVisible = lv.getFirstVisiblePosition() - lv.getHeaderViewsCount();
            child = i - firstVisible;
            if(child < 0 || child >= lv.getChildCount()) {
                continue;
            }
            if(updated.contains(i)) continue;
            Log.d("Debug", "Updating child:" + Integer.toString(child));
            LinearLayout row = (LinearLayout) lv.getChildAt(child);
            if(likeable.get(i) == 0) {
                LinearLayout btn = (LinearLayout) row.findViewById(R.id.btn_like);
                btn.setClickable(false);
                ImageView imgView = (ImageView) row.findViewById(R.id.img_like);
                imgView.setImageDrawable(getResources().getDrawable(R.drawable.ic_like_selected));
                TextView txtView = (TextView) row.findViewById(R.id.text_like);
                txtView.setTextColor(Color.parseColor("#60007c"));
            }
            if(dislikeable.get(i) == 0) {
                LinearLayout btn = (LinearLayout) row.findViewById(R.id.btn_dislike);
                btn.setClickable(false);
                ImageView imgView = (ImageView) row.findViewById(R.id.img_dislike);
                imgView.setImageDrawable(getResources().getDrawable(R.drawable.ic_dislike_selected));
                TextView txtView = (TextView) row.findViewById(R.id.text_dislike);
                txtView.setTextColor(Color.parseColor("#60007c"));
            }
            Log.d("Debug", "Adding child" + Integer.toString(i) + "TO the updated list");
            updated.add(i);
        }
    }

每次用户滚动列表视图时,我都会运行此代码:

ListView lv = ((ListView) findViewById(R.id.post_list));
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub
        updateButtons();
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        // TODO Auto-generated method stub
        updateButtons();
    }
});
4

3 回答 3

1

目前还不是很清楚是什么问题。当您通过滚动到达最后一项时,第一项(来自适配器的一项或第一个可见的)再次更新?

我个人的看法是,您以错误的方式处理了这个问题。从问题来看,您似乎想更新ListView. 您应该通过更新适配器中的数据并调用notifyDataSetChanged()而不是使用OnScrollListener. 这对用户操作(喜欢/不喜欢的项目)是有意义的,我怀疑你在用户滚动时创建了一个非常尴尬的喜欢/不喜欢系统。

lv.getCount()此外,如果您只想触摸可见行(使用您当前执行的代码,您不妨一次性在适配器中进行更新并调用notifyDatasetChanged()),那么使用迭代所有适配器项是没有意义的。使用getFirstVisiblePosition()getLastVisiblePosition()。您可以通过不调用该updateButtons()方法来优化代码,除非您由于滚动而在屏幕上出现了一个新行,您可以从该onScroll()方法的参数中观察/计算(我看到一个updated包含已更新项目的列表?!) .

于 2013-06-01T13:39:03.947 回答
1

试试这个代码。它对我来说很好。

您的适配器类将如下所示。

package com.rajesh.getselecteditem;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;

public class ListAdapter extends BaseAdapter {
    Context ctx;
    LayoutInflater lInflater;
    ArrayList<Position> arraylist;

    ListAdapter(Context context, ArrayList<Position> products) {
        ctx = context;
        arraylist = products;
        lInflater = (LayoutInflater) ctx
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return arraylist.size();
    }

    @Override
    public Object getItem(int position) {
        return arraylist.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (view == null) {
            view = lInflater.inflate(R.layout.item, parent, false);
        }

        Position pos = getselectedposition(position);
        ((TextView) view.findViewById(R.id.Textview1)).setText(""+pos.position);

        final ImageView imageView1 = (ImageView) view.findViewById(R.id.imageView1);

        CheckBox chkbox = (CheckBox) view.findViewById(R.id.cbBox);

        chkbox.setTag(position);
        chkbox.setChecked(pos.ischeckedflag);
        imageView1.setTag(position);



        chkbox.setOnCheckedChangeListener( new OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                getselectedposition((Integer) buttonView.getTag()).ischeckedflag = isChecked;
                if(isChecked)
                {
                    imageView1.setVisibility(View.GONE);
                }
                else if(!isChecked)
                {
                    imageView1.setVisibility(View.VISIBLE);
                }
            }
        });


        return view;
    }

    Position getselectedposition(int position) {
        return ((Position) getItem(position));
    }

    ArrayList<Position> getcheckedposition() {
        ArrayList<Position> checkedposition = new ArrayList<Position>();
        for (Position p : arraylist) {
            if (p.ischeckedflag)
                checkedposition.add(p);
        }
        return checkedposition;
    }


}

你的活动就像下面的课程

package com.rajesh.getselecteditem;
import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

    ArrayList<Position> listitems = new ArrayList<Position>();
    ListAdapter listAdapter;
    ListView lvMain ;

      /** Called when the activity is first created. */
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         lvMain = (ListView) findViewById(R.id.listview);



        arraylistvalueadding();
        listAdapter = new ListAdapter(this, listitems);


        lvMain.setAdapter(listAdapter);
      }

      void arraylistvalueadding() {
        for (int i = 1; i <= 20; i++) {
            listitems.add(new Position(i,false));
        }
      }

}

您的职位类别如下。

public class Position {
      int  position;    
      boolean ischeckedflag;


      Position(int name, boolean flag) {
          position = name;     
          ischeckedflag = flag;
      }
    }

只需使用列表视图设计您的 main.xml 类。

您的 listitem.xml 如下所示。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <CheckBox
        android:id="@+id/cbBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical" >
    </CheckBox>

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:orientation="vertical"
        android:layout_weight="1" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@+id/Textview1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text=""
            android:textSize="20sp" >
        </TextView>       
    </LinearLayout>

</LinearLayout>
于 2013-06-01T14:01:48.653 回答
0

好的,我自己解决了这个问题。问题不在代码中,也不是因为我的软件。这件事是我发现的一个可能的 android 错误。:) 我必须再次明确设置数据,即使它是默认的。此代码有效:

if(likeable.get(i) == 0) {
    LinearLayout btn = (LinearLayout) row.findViewById(R.id.btn_like);
    btn.setClickable(false);
    ImageView imgView = (ImageView) row.findViewById(R.id.img_like);
    imgView.setImageDrawable(getResources().getDrawable(R.drawable.ic_like_selected));
    TextView txtView = (TextView) row.findViewById(R.id.text_like);
    txtView.setTextColor(Color.parseColor("#60007c"));
} else {
    LinearLayout btn = (LinearLayout) row.findViewById(R.id.btn_like);
    btn.setClickable(true);
    ImageView imgView = (ImageView) row.findViewById(R.id.img_like);
    imgView.setImageDrawable(getResources().getDrawable(R.drawable.ic_like));
    TextView txtView = (TextView) row.findViewById(R.id.text_like);
    txtView.setTextColor(Color.parseColor("#555555"));
}
if(dislikeable.get(i) == 0) {
    LinearLayout btn = (LinearLayout) row.findViewById(R.id.btn_dislike);
    btn.setClickable(false);
    ImageView imgView = (ImageView) row.findViewById(R.id.img_dislike);
    imgView.setImageDrawable(getResources().getDrawable(R.drawable.ic_dislike_selected));
    TextView txtView = (TextView) row.findViewById(R.id.text_dislike);
    txtView.setTextColor(Color.parseColor("#60007c"));
} else {
    LinearLayout btn = (LinearLayout) row.findViewById(R.id.btn_dislike);
    btn.setClickable(true);
    ImageView imgView = (ImageView) row.findViewById(R.id.img_dislike);
    imgView.setImageDrawable(getResources().getDrawable(R.drawable.ic_dislike));
    TextView txtView = (TextView) row.findViewById(R.id.text_dislike);
    txtView.setTextColor(Color.parseColor("#555555"));
}

为了确切地知道发生了什么,我尽可能多地描述它。我在else上面代码部分设置的属性正是默认情况下在行上设置的属性(使用布局)。事情是if不正确的(我们不需要做任何改变),我们只是跳过它们。当滚动列表时,他们被 android 覆盖(这是错误)。因此,我在代码(部分)中明确将它们恢复为默认值,else代码按预期工作。

谢谢大家的回答。

于 2013-06-01T15:28:54.773 回答