我正在尝试创建一个任务管理器,而我只有一个问题。我有一个可以膨胀的列表视图。列表视图中的所有元素都是正确的。问题是,当我选择一个项目时,列表视图将选择另一个项目。我听说listviews重新填充列表,因为它向下滚动以节省内存。我认为这可能是某种问题。这是problem的图片。 如果我有更多的应用程序加载,那么它将继续一次选择多个。
以下是我的适配器和活动的代码以及与XML相关的
public class TaskAdapter extends BaseAdapter{
private Context mContext;
private List<TaskInfo> mListAppInfo;
private PackageManager mPack;
public TaskAdapter(Context c, List<TaskInfo> list, PackageManager pack) {
mContext = c;
mListAppInfo = list;
mPack = pack;
}
@Override
public int getCount() {
return mListAppInfo.size();
}
@Override
public Object getItem(int position) {
return mListAppInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
TaskInfo entry = mListAppInfo.get(position);
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(mContext);
//System.out.println("Setting LayoutInflater in TaskAdapter " +mContext +" " +R.layout.taskinfo +" " +R.id.tmbox);
convertView = inflater.inflate(R.layout.taskinfo,null);
}
ImageView ivIcon = (ImageView)convertView.findViewById(R.id.tmImage);
ivIcon.setImageDrawable(entry.getIcon());
TextView tvName = (TextView)convertView.findViewById(R.id.tmbox);
tvName.setText(entry.getName());
convertView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
final CheckBox checkBox = (CheckBox)v.findViewById(R.id.tmbox);
if(v.isSelected())
{
System.out.println("Listview not selected ");
//CK.get(arg2).setChecked(false);
checkBox.setChecked(false);
v.setSelected(false);
}
else
{
System.out.println("Listview selected ");
//CK.get(arg2).setChecked(true);
checkBox.setChecked(true);
v.setSelected(true);
}
}
});
return convertView;
public class TaskManager extends Activity implements Runnable
{
private ProgressDialog pd;
private TextView ram;
private String s;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.taskpage);
setTitleColor(Color.YELLOW);
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run()
{
//System.out.println("In Taskmanager Run() Thread");
final PackageManager pm = getPackageManager();
final ListView box = (ListView) findViewById(R.id.cBoxSpace);
final List<TaskInfo> CK = populate(box, pm);
runOnUiThread(new Runnable()
{
@Override
public void run()
{
ram.setText(s);
box.setAdapter(new TaskAdapter(TaskManager.this, CK, pm));
//System.out.println("In Taskmanager runnable Run()");
endChecked(CK);
}
});
handler.sendEmptyMessage(0);
}
Taskinfo.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/tmImage"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="centerCrop"
android:adjustViewBounds="false"
android:focusable="false" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tmbox"
android:lines="2"/>
</LinearLayout>
Taskpage.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/cBoxSpace"
android:layout_width="wrap_content"
android:layout_height="400dp"
android:orientation="vertical"/>
<TextView
android:id="@+id/RAM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
<Button
android:id="@+id/endButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="End Selected Tasks" />
</LinearLayout>
通过一次点击选择多个项目的任何想法将非常感激。我一直在搞乱不同的实现,听众和listadapters,但无济于事。
答案 0 :(得分:1)
我认为关键是你只在视图中保存检查状态(v.setSelected)。
您重复使用这些视图,因此其复选框始终不会更改其状态。
您可以创建一个状态数组来保存每个TaskInfo的每个检查状态,并在创建视图时检查该数组。
例如
// default is false
ArrayList<Boolean> checkingStates = new ArrayList<Boolean>(mListAppInfo.size());
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
TaskInfo entry = mListAppInfo.get(position);
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(R.layout.taskinfo,null);
}
ImageView ivIcon = (ImageView)convertView.findViewById(R.id.tmImage);
ivIcon.setImageDrawable(entry.getIcon());
TextView tvName = (TextView)convertView.findViewById(R.id.tmbox);
tvName.setText(entry.getName());
final CheckBox checkBox = (CheckBox)v.findViewById(R.id.tmbox);
checkBox.setChecked(checkingStates.get(position));
convertView.setSelected(checkingStates.get(position));
convertView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
if(v.isSelected())
{
System.out.println("Listview not selected ");
//CK.get(arg2).setChecked(false);
checkBox.setChecked(false);
v.setSelected(false);
checkingStates.get(position) = false;
}
else
{
System.out.println("Listview selected ");
//CK.get(arg2).setChecked(true);
checkBox.setChecked(true);
v.setSelected(true);
checkingStates.get(position) = true;
}
}
});
return convertView;
}
答案 1 :(得分:1)
我不是100%确定您要执行的操作,但部分问题可能与onClick
方法中的条件有关:
if(v.isSelected())
我想你想要阅读
if(v.isChecked())
isSelected
继承自View,它意味着与isChecked
此外,CheckBox是否被选中与数据模型无关,因为它是一个循环视图。你的CheckBox应该根据entry
进行检查(我假设你的TextInfo
类有一个返回布尔值的isChecked()
方法:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
TaskInfo entry = mListAppInfo.get(position);
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(mContext);
//System.out.println("Setting LayoutInflater in TaskAdapter " +mContext +" " +R.layout.taskinfo +" " +R.id.tmbox);
convertView = inflater.inflate(R.layout.taskinfo,null);
}
ImageView ivIcon = (ImageView)convertView.findViewById(R.id.tmImage);
ivIcon.setImageDrawable(entry.getIcon());
TextView tvName = (TextView)convertView.findViewById(R.id.tmbox);
tvName.setText(entry.getName());
CheckBox checkBox = (CheckBox)v.findViewById(R.id.tmbox);
checkBox.setChecked(entry.isChecked());
}
我认为您不需要附加到View.OnClickListener
的{{1}}。您应该在convertView
附带的OnItemClickListener
处理此问题。假设您的ListView
被称为ListView
,listView
个实例有TaskInfo
和setChecked
方法:
isChecked
答案 2 :(得分:0)
First of all don't set the list checked or unchecked on view position.
because view position means only visible items position in your listview but you would like to set checked or uncheked status on a particular list item.
that's why this problem arising in your code.
You have the need to set the items checked and unchecked on your custom arraylist getter setter like the code i have attached below:
package com.app.adapter;
public class CategoryDynamicAdapter {
public static ArrayList<CategoryBean> categoryList = new ArrayList<CategoryBean>();
Context context;
Typeface typeface;
public static String videoUrl = "" ;
Handler handler;
Runnable runnable;
// constructor
public CategoryDynamicAdapter(Activity a, Context context, Bitmap [] imagelist,ArrayList<CategoryBean> list) {
this.context = context;
this.categoryList = list;
this.a = a;
}
// Baseadapter to the set the data response from web service into listview.
public BaseAdapter mEventAdapter = new BaseAdapter() {
@Override
public int getCount() {
return categoryList.size();
}
@Override
public Object getItem(int position) {
return categoryList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
class ViewHolder {
TextView title,category,uploadedBy;
ImageView image;
RatingBar video_rating;
Button report_video ,Flag_video;
}
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder vh = null ;
if(convertView == null) {
vh = new ViewHolder();
convertView = LayoutInflater.from(context).inflate (R .layout.custom_category_list_layout,null,false);
vh.title = (TextView) convertView .findViewById (R.id.title);
vh.image = (ImageView) convertView.findViewById(R.id.Imagefield);
convertView.setTag(vh);
}
else
{
vh=(ViewHolder) convertView.getTag();
}
try
{
final CategoryBean Cb = categoryList.get(position);
//pay attention to code below this line i have shown here how to select a listview using arraylist getter setter objects
String checkedStatus = Cb.getCheckedStringStaus();
if(checkdStatus.equal("0")
{
System.out.println("Listview not selected ");
//CK.get(arg2).setChecked(false);
checkBox.setChecked(false);
v.setSelected(false);
}
else ////checkdStatus.equal("1")
{
System.out.println("Listview selected ");
//CK.get(arg2).setChecked(true);
checkBox.setChecked(true);
v.setSelected(true);
}
catch (Exception e)
{
e.printStackTrace();
}