Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 Arrayadapter与OnClick侦听器匹配_Android_Eclipse_View_Onclick_Android Arrayadapter - Fatal编程技术网

Android Arrayadapter与OnClick侦听器匹配

Android Arrayadapter与OnClick侦听器匹配,android,eclipse,view,onclick,android-arrayadapter,Android,Eclipse,View,Onclick,Android Arrayadapter,这是我的自定义arrayadapter类,我想在单击每行按钮时更改每行按钮的图像资源,它可以工作,但另一行中的另一个按钮也会更改。谢谢你的帮助 public class Coursadapter extends ArrayAdapter<String> { Context context; int layoutResourceId; ArrayList<String> data = null; WeatherHolder holder;

这是我的自定义arrayadapter类,我想在单击每行按钮时更改每行按钮的图像资源,它可以工作,但另一行中的另一个按钮也会更改。谢谢你的帮助

public class Coursadapter extends ArrayAdapter<String> {

    Context context;
    int layoutResourceId;
    ArrayList<String> data = null;
    WeatherHolder holder;

    public Coursadapter(Context context, int layoutResourceId,
            ArrayList<String> data) {
        // super(context, layoutResourceId, data, coeff);
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;

    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, null);

            holder = new WeatherHolder();
            holder.name = (TextView) row.findViewById(R.id.item_cours_name);
            holder.b = (ImageButton) row.findViewById(R.id.button);
            holder.b.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    WeatherHolder w = (WeatherHolder) v.getTag();
                    w.b.setImageResource(R.drawable.butgreen);
                }
            });
            row.setTag(holder);

        } else {
            holder = (WeatherHolder) row.getTag();
        }

        holder.b.setTag(holder);
        String name1 = data.get(position);
        holder.name.setText(name1);

        return row;
    }

    static class WeatherHolder {

        TextView name;
        ImageButton b;
    }
}
公共类Coursadapter扩展了ArrayAdapter{
语境;
国际布局资源;
ArrayList数据=null;
风挡;
公共Coursadapter(上下文上下文、内部布局资源ID、,
ArrayList数据){
//超级(上下文、布局资源ID、数据、系数);
超级(上下文、布局资源ID、数据);
this.layoutResourceId=layoutResourceId;
this.context=上下文;
这个数据=数据;
}
公共视图getView(int位置、视图转换视图、视图组父视图){
视图行=转换视图;
if(行==null){
LayoutInflater充气器=((活动)上下文)。getLayoutInflater();
行=充气机。充气(布局资源ID,空);
支架=新的密封支架();
holder.name=(TextView)row.findViewById(R.id.item\u cours\u name);
holder.b=(ImageButton)row.findViewById(R.id.button);
holder.b.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//TODO自动生成的方法存根
WeatherHolder w=(WeatherHolder)v.getTag();
w、 b.setImageResource(R.drawable.butgreen);
}
});
row.setTag(支架);
}否则{
holder=(WeatherHolder)row.getTag();
}
holder.b.setTag(holder);
字符串名称1=data.get(位置);
holder.name.setText(name1);
返回行;
}
静态类风挡{
文本视图名称;
图像按钮b;
}
}

您可以声明变量int,该变量将保存所选项目的位置,并且

public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
            mSelectedItem = position;
            mAdapter.notifyDataSetChanged();
    }
听着,我试着用这段代码工作,在你的活动中实现OnClickListener

public class MainActivity extends Activity  implements OnClickListener
在getView方法中

public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context)
                    .getLayoutInflater();
            row = inflater.inflate(layoutResourceId, null);

            holder = new WeatherHolder();
            holder.name = (TextView) row.findViewById(R.id.item_cours_name);
            holder.b = (ImageButton) row.findViewById(R.id.button);
            holder.b.setOnClickListener(MainActivity.this);
并且实现Onclick方法来设置资源

@Override
public void onClick(View v) {
    WeatherHolder w = (WeatherHolder) v.getTag();
    w.b.setImageResource(android.R.drawable.star_big_on);
}

代码的问题是OnClickListener设置在错误的位置

考虑一下
getView()
中if/else语句的结果。如果传入该方法的
convertView
为空,则可能是首次创建视图(以及包含该视图的ListView)——例如,您正在启动包含该ListView的活动。如果该值不为null,则意味着您正在循环一个以前在屏幕上但现在不再在屏幕上的视图

如果你仔细观察,你会发现你的OnClickListener只在第一种情况下被设置——一个全新的视图。一旦你滚动一点,你的听众将永远不会正确地连接到那些来自屏幕外的视图

更好的
getView()
方法是:

public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;

    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, null);

        holder = new WeatherHolder();
        holder.name = (TextView) row.findViewById(R.id.item_cours_name);
        holder.b = (ImageButton) row.findViewById(R.id.button);

        row.setTag(holder);

    } else {
        holder = (WeatherHolder) row.getTag();
    }

    String name1 = data.get(position);
    holder.name.setText(name1);

    holder.b.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {                    
                ((ImageButton)v).setImageResource(R.drawable.butgreen);
            }
        });

    return row;
}

编辑:添加到我下面评论的另一个修复中。

发生这种情况的原因是适配器在滚动时回收视图

例如,假设一次屏幕上总共有15行和5行。if(row==null)部分仅对前5行执行。当您向下滚动到第6行时,它使用第一行的视图。这就是为什么应该在if-else子句之后设置视图的内容。现在,当第6行进入屏幕时,该行不为空。它可以看到第一排。当它执行holder.name.setText(name1);,它将第1行的名称替换为第6行的名称。类似地,第7行使用第2行的视图,依此类推

现在,假设您单击第一行的按钮。第一行的视图更改,w.b.setImageResource(R.drawable.butgreen);设置第一行按钮的图像资源。当您滚动到第6行时,它使用第一行的视图。但是您正在将only holder.name设置为第6行的名称。第一行按钮的图像资源将保留在那里,从而导致您的问题

解决方案:创建另一个ArrayList并在此列表中存储按钮的状态。在你的例子中,我假设按钮的颜色是“红色”或“绿色”。您可以在每个位置存储“红色”或“绿色”,表示每个按钮当前的颜色(您可以将此ArrayList初始化为红色)。然后,当加载每一行时,可以将图像资源与该行的名称一起设置。请看下面的代码。我已经在我添加的行中添加了注释

public class Coursadapter extends ArrayAdapter<String> {

Context context;
int layoutResourceId;
ArrayList<String> data = null;
WeatherHolder holder;
ArrayList<String> colors; // Stores the color of each button

public Coursadapter(Context context, int layoutResourceId, ArrayList<String> data) {
    // super(context, layoutResourceId, data, coeff);
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
    this.colors = new ArrayList<>(Collections.nCopies(data.size(), "red")); // initialize all the buttons to red color
}

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


    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new WeatherHolder();
        holder.name = (TextView)row.findViewById(R.id.item_cours_name);
        holder.b=(ImageButton) row.findViewById(R.id.button);
        holder.b.setTag(holder);
        row.setTag(holder);
    }
    else
    {
        holder = (WeatherHolder)row.getTag();
    }

    if(colors.get(position).equals("red")) {
        holder.b.setImageResource(R.drawable.butred); // set the colors of the button to red or whatever you need
    } else {
        holder.b.setImageResource(R.drawable.butgreen); // set the colors of the button to green
    }

    holder.b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            WeatherHolder w = (WeatherHolder) v.getTag();
            //w.b.setImageResource(R.drawable.butgreen);
            colors.set(position, "green"); // update the ArrayList colors
        }
    });
    String name1 = data.get(position);
    holder.name.setText(name1);


    return row;
}

static class WeatherHolder
{

    TextView name;
    ImageButton b;
}
}
公共类Coursadapter扩展了ArrayAdapter{
语境;
国际布局资源;
ArrayList数据=null;
风挡;
ArrayList colors;//存储每个按钮的颜色
公共Coursadapter(上下文上下文、int-layoutResourceId、ArrayList数据){
//超级(上下文、布局资源ID、数据、系数);
超级(上下文、布局资源ID、数据);
this.layoutResourceId=layoutResourceId;
this.context=上下文;
这个数据=数据;
this.colors=newarraylist(Collections.nCopies(data.size(),“red”);//将所有按钮初始化为红色
}
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
视图行=转换视图;
if(行==null)
{
LayoutInflater充气器=((活动)上下文)。getLayoutInflater();
行=充气机。充气(layoutResourceId,父级,false);
支架=新的密封支架();
holder.name=(TextView)row.findViewById(R.id.item\u cours\u name);
holder.b=(ImageButton)row.findViewById(R.id.button);
holder.b.setTag(holder);
row.setTag(支架);
}
其他的
{
holder=(WeatherHolder)row.getTag();
}
if(colors.get(position.equals)(“红色”)){
holder.b.setImageResource(R.drawable.butred);//将按钮的颜色设置为红色或您需要的任何颜色
}否则{
b.b.组
public class Coursadapter extends ArrayAdapter<String> {

Context context;
int layoutResourceId;
ArrayList<String> data = null;
WeatherHolder holder;
ArrayList<String> colors; // Stores the color of each button

public Coursadapter(Context context, int layoutResourceId, ArrayList<String> data) {
    // super(context, layoutResourceId, data, coeff);
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
    this.colors = new ArrayList<>(Collections.nCopies(data.size(), "red")); // initialize all the buttons to red color
}

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


    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new WeatherHolder();
        holder.name = (TextView)row.findViewById(R.id.item_cours_name);
        holder.b=(ImageButton) row.findViewById(R.id.button);
        holder.b.setTag(holder);
        row.setTag(holder);
    }
    else
    {
        holder = (WeatherHolder)row.getTag();
    }

    if(colors.get(position).equals("red")) {
        holder.b.setImageResource(R.drawable.butred); // set the colors of the button to red or whatever you need
    } else {
        holder.b.setImageResource(R.drawable.butgreen); // set the colors of the button to green
    }

    holder.b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            WeatherHolder w = (WeatherHolder) v.getTag();
            //w.b.setImageResource(R.drawable.butgreen);
            colors.set(position, "green"); // update the ArrayList colors
        }
    });
    String name1 = data.get(position);
    holder.name.setText(name1);


    return row;
}

static class WeatherHolder
{

    TextView name;
    ImageButton b;
}
}