Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-带滚动的Listview/Gridview项目选择_Android_Listview_Scroll_Recycle_Multichoiceitems - Fatal编程技术网

Android-带滚动的Listview/Gridview项目选择

Android-带滚动的Listview/Gridview项目选择,android,listview,scroll,recycle,multichoiceitems,Android,Listview,Scroll,Recycle,Multichoiceitems,我是android新手,我刚刚开始编写一个简单的应用程序来尝试不同的东西 我正在编写一个ListView(和GridView一样),但我出了点问题。每个项目都是一对图像和一个文本字段 | img|uuuuuuu文本uuuu124; 我希望能够选择任意数量的列表项,在将所选项传递给下一个活动之前,让它们在所有选择过程中都处于启发状态。如果我想 取消选择其中的一个,我只需重新单击该项即可使选择消失。为此,我使用了一个自定义选择器,这样当按下项目时,它会改变颜色 如果所有项目都包含在屏幕中,则一切正

我是android新手,我刚刚开始编写一个简单的应用程序来尝试不同的东西

我正在编写一个ListView(和GridView一样),但我出了点问题。每个项目都是一对图像和一个文本字段

| img|uuuuuuu文本uuuu124;

我希望能够选择任意数量的列表项,在将所选项传递给下一个活动之前,让它们在所有选择过程中都处于启发状态。如果我想 取消选择其中的一个,我只需重新单击该项即可使选择消失。为此,我使用了一个自定义选择器,这样当按下项目时,它会改变颜色

如果所有项目都包含在屏幕中,则一切正常。但是,一旦它们的数量增加,循环利用开始起作用,从屏幕上消失的选定项目的启发就消失了。我已经调试了项目的状态,那些失去启发的项目仍然被正确选择,所以我认为这只是一个问题,当项目从设备屏幕上消失后恢复时,图形如何重新加载

以下是活动布局的代码:

<!-- items_selection.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="match_parent"
android:orientation="vertical"
android:background="@color/Background">

<ListView
    android:id="@+id/item_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:divider="@color/divider"
    android:dividerHeight="3dp"
    android:choiceMode="multipleChoice"
    android:listSelector="@drawable/list_selector">
</ListView>

</LinearLayout>
在适配器中,单击处理程序之前),但问题仍然存在。有人能帮我解决这个问题吗

~~~~~~~~~~~~~~~~~~~~~~~解决方案~~~~~~~~~~~~~~~~~~ 选择器似乎没有遵循项目及其视图的循环。在这种情况下,必须有一个更好、更优雅的解决方案来利用选择器。但在我所有的尝试中,没有一次成功。此解决方案是最佳解决方案,不使用选择器

public View getView(final int position, View convertView, ViewGroup parent) {

View view = convertView;
ViewHolder holder;

if(view == null) {
    LayoutInflater li = sActivity.getLayoutInflater();
    view = li.inflate(R.layout.list_row, null);

    holder = new ViewHolder();
    holder.text = (TextView)view.findViewById(R.id.item_name);
    holder.img = (ImageView)view.findViewById(R.id.item_image);

    view.setTag(holder);
}

else {
    holder = (ViewHolder)view.getTag();
}

holder.text.setText(items.get(position).getName());
holder.img.setImageResource(items.get(position).getImage());

if(items.get(position).isSelected()){
    view.setBackgroundResource(R.drawable.rect_sel);
}else{
    view.setBackgroundResource(R.drawable.rect);
}

view.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View viewitem) {

        if (!viewitem.isSelected() && !items.get(position).isSelected()) {
            viewitem.setBackgroundResource(R.drawable.rect_sel);
            viewitem.setSelected(true);
            items.get(position).setSelected(true);
        }

        else {
            viewitem.setBackgroundResource(R.drawable.rect);
            viewitem.setSelected(false);
            items.get(position).setSelected(false);
        }
    }
    });

    return view;
}

private static class ViewHolder{
    public TextView text;
    public ImageView img;
}
在list_row.xml文件中,可以删除以下行:

android:background="@drawable/list_selector"

必须在getView方法内定义视图的当前选择状态

添加此行:

viewitem.setSelected(items.get(position).isSelected());
创建viewholder后,如下所示:

holder.img.setImageResource(items.get(position).getImage());
viewitem.setSelected(items.get(position).isSelected());
在您的
getView()
方法中,只需添加以下测试:

if (items.get(position).isSelected()){
   view.setBackgroundResource(R.drawable.rect_sel);
} else {
   view.setBackgroundResource(R.drawable.rect);
}

或者只是
view.setSelected(items.get(position.isSelected())。虽然您已经为列表项设置了选择器。

我认为您应该为您的RelativeLayout设置id,然后将其添加到ViewHolder

private static class ViewHolder{
    public TextView text;
    public ImageView img;
    RelativeLayout rl;
}
之后,单击RelativeLayout时处理事件,然后更改RelativeLayout的背景

 public View getView(...)
    ...
    ...
    // you should update the state of relative layout first
     if (items.get(position).isSelected()) {
        holder.setBackgroundColor(Color.parseColor("#ffff00"));
    }else{
         holder.setBackgroundColor(Color.parseColor("#ff0000"));
    }

    holder.rl.setOnClickListener(new View.OnClickListener(){ //remmember it is rl.setOnClick... not view.setOnClick...
        public void onClick(View v) {
              if (!items.get(position).isSelected()) {
                  items.get(position).setSelected(true);
                  holder.setBackgroundColor(Color.parseColor("#ffff00"));
              }else {
                  items.get(position).setSelected(false);
                  holder.setBackgroundColor(Color.parseColor("#ff0000"));
              }
        }
    });
}
建议
您应该像这样修改行布局(我已经删除了LinearLayout,但新布局仍然很好)


记住,你的列表行布局更简单,那么你的列表视图将滚动得更快,更平滑,并防止一些恼人的错误


当我尝试访问
holder.rl.setSelected(true)时,希望这对我有所帮助它告诉我“变量持有者是从内部类访问的,需要声明为final”。所以我做了最后的决定,但问题仍然存在。@Panda_零问题只在滚动时生成,对吗?如果可能的话,您可以再次更新完整的适配器源代码吗?我刚刚用您的解决方案更新了我在适配器中更改的代码。@Panda\u Zero我已经修改了我的代码,请检查一下。谢谢。是的,我错配了侦听器签名,我在代码中使用了
holder.rl.setOnClickListener(…)
。不管怎样,再次应用您建议的修改,什么都不会发生:当他们退出屏幕时,所选项目仍然会关闭,并且在再次进入时不会被点亮。通过使用您的第一个解决方案,我确实做了一些更改:现在当我选择一个项目时,它不会点亮。但当我向下滚动然后再向上滚动时,它就被照亮了。我认为这可以解决一些问题,但是为什么选择器解决方案不起作用呢?我希望它能够识别回收项目的状态,但它似乎只是被忽略了,即使我放置
view.setSelected(items.get(position.issselected())选择器不工作,因为“setBackgroundResource()”将删除该选择器并将新的可绘制文件作为背景。如果您想使用第一种解决方案,您可以从后台删除选择器,并在单击侦听器中使用setBackgroundResource()。是的,
view.setBackgroundResource(“梯度”)覆盖选择器。我不明白的是,为什么即使我用
view.setSelected(items.get(position.isSelected())显式地告诉选择器,选择器本身也不会对项目的循环做出反应。我甚至尝试用
view.setBackgroundResource(R.drawable.list\u选择器)重新加载它但没有任何变化。使用此解决方案,问题仍然存在。
viewitem.setSelected(items.get(position).isSelected());
holder.img.setImageResource(items.get(position).getImage());
viewitem.setSelected(items.get(position).isSelected());
if (items.get(position).isSelected()){
   view.setBackgroundResource(R.drawable.rect_sel);
} else {
   view.setBackgroundResource(R.drawable.rect);
}
private static class ViewHolder{
    public TextView text;
    public ImageView img;
    RelativeLayout rl;
}
 public View getView(...)
    ...
    ...
    // you should update the state of relative layout first
     if (items.get(position).isSelected()) {
        holder.setBackgroundColor(Color.parseColor("#ffff00"));
    }else{
         holder.setBackgroundColor(Color.parseColor("#ff0000"));
    }

    holder.rl.setOnClickListener(new View.OnClickListener(){ //remmember it is rl.setOnClick... not view.setOnClick...
        public void onClick(View v) {
              if (!items.get(position).isSelected()) {
                  items.get(position).setSelected(true);
                  holder.setBackgroundColor(Color.parseColor("#ffff00"));
              }else {
                  items.get(position).setSelected(false);
                  holder.setBackgroundColor(Color.parseColor("#ff0000"));
              }
        }
    });
}
    <!-- list_row.xml --> 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >

  <ImageView 
     android:id="@+id/item_image"
     android:layout_marginRight="5dip"
     android:padding="3dip"
     android:layout_alignParentLeft="true"
     android:layout_width="@dimen/img_side"
     android:layout_height="@dimen/img_side" />

<TextView
    android:id="@+id/item_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/item_image"
    android:layout_centerVertical="true"
    android:textColor="@color/black"
    android:textSize="@dimen/textnorm"
    />

</RelativeLayout>