我想更新ListView
中的按钮。我目前的代码工作正常,但有一个小故障,当到达最后一个项目时,它突然更新第一个项目与上一篇文章中的错误数据,因为它是最后一篇文章。我不知道会发生什么,在我的log我没有得到任何表明第一项正在更新的内容。
我从这个similar question获得了这段代码和想法。
以下是我使用的代码:
/**
* 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时都会运行此代码:
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();
}
});
答案 0 :(得分:1)
目前尚不清楚问题是什么。当您通过滚动到达最后一个项目时,第一个项目(来自适配器或第一个可见项目)再次更新?
我的个人意见是你以错误的方式接近了这一点。从问题看,您似乎想要更新ListView
的每一行中的一些按钮。您应该通过更新适配器中的数据并调用notifyDataSetChanged()
而不是使用OnScrollListener
来执行此操作。这对于用户操作(喜欢/不喜欢的项目)是有意义的,我怀疑你在用户滚动上创建了一个非常尴尬的喜欢/不喜欢的系统。
此外,如果您只想触摸可见行,使用lv.getCount()
迭代所有适配器项是没有意义的(使用您当前执行的代码,也可以在适配器中进行更新一气呵成,然后致电notifyDatasetChanged()
)。使用getFirstVisiblePosition()
和getLastVisiblePosition()
。您可以通过不调用updateButtons()
方法来优化代码,除非由于滚动而在屏幕上出现新行,您可以从onScroll()
方法的参数观察/计算(我看到一个updated
列表,其中包含已更新的项目?!)。
答案 1 :(得分:1)
尝试使用此代码。它对我来说很好。
您的Adapter类如下所示。
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>
答案 2 :(得分:0)
好的,我自己解决了这个问题。问题不在代码中,也不在于我的软件。事情是我发现的一个可能的机器人bug。 :)我必须再次显式设置数据,即使它是默认数据。这段代码有效:
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
部分)中的默认值,代码按预期工作。
谢谢大家的回答。