ListView的ImageView onClick也改变了其他行

时间:2013-08-15 05:49:49

标签: android android-listview

我有ListView。 ListView的行中有ImageView。我已将onClick属性附加到ImageView,而我的onClick函数是

public void alarmClick(View v)
{
    ImageView bell = (ImageView)v.findViewById(R.id.mEventImage);
    bell.setImageResource(R.drawable.bell_on);
    if(bell.getTag() == null)
    {
        bell.setImageResource(R.drawable.bell_on);
        bell.setTag(R.drawable.bell_on);
    }
    else if((Integer)bell.getTag() == R.drawable.bell_on)
    {
        bell.setImageResource(R.drawable.bell_off);
        bell.setTag(R.drawable.bell_off);
    }
    else
    {
        bell.setImageResource(R.drawable.bell_on);
        bell.setTag(R.drawable.bell_on);
    }
}

我正在尝试切换ImageView来源,但是当我点击ImageView当时不在屏幕上的许多其他行ImageView也会切换。这可能是因为视图在ListView中被回收。有关如何为每个唯一行做的任何建议。

适配器类

package com.example.drawer;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;


public class EventAdapter extends ArrayAdapter<EventList> {

    Context context;
    ArrayList<EventList> data;
    int layoutResourceId;

    public EventAdapter(Context context, int textViewResourceId, ArrayList<EventList> data) {
        super(context, textViewResourceId, data);
        this.context = context;
        this.data = data;
        this.layoutResourceId = textViewResourceId;
        // TODO Auto-generated constructor stub
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        EventHolder holder =  null;
        if(row == null)
        {
            LayoutInflater inflator = ((Activity)context).getLayoutInflater();
            row = inflator.inflate(layoutResourceId, parent, false);
            holder = new EventHolder();
            holder.coord = (TextView)row.findViewById(R.id.eventCoor);
            holder.icon = (ImageView)row.findViewById(R.id.icon);
            holder.eventName = (TextView)row.findViewById(R.id.eventNam);
            holder.location = (TextView)row.findViewById(R.id.eventLoc);
            holder.time = (TextView)row.findViewById(R.id.eventTime);
            row.setTag(holder);

        }
        else
        {
            holder = (EventHolder)row.getTag();
        }
        EventList listItem = data.get(position);
        ImageHelper imageHelper = new ImageHelper();
        Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ipl);
        Bitmap newIcon = imageHelper.getRoundedCornerBitmap(icon, 200);
        holder.coord.setText(listItem.coord);
        holder.eventName.setText(listItem.eventName);
        holder.location.setText(listItem.location);
        holder.time.setText(listItem.time);
        holder.icon.setImageBitmap(newIcon);
        holder.id = listItem.id;
        holder.day = listItem.day;
        //Log.d("ListView", "Executed");
        return row;

    }


    static class EventHolder
    {
        ImageView icon;
        TextView eventName;
        TextView location;
        TextView time;
        TextView coord;
        int id;
        int day;
    }
}

2 个答案:

答案 0 :(得分:0)

是的,原因是视图被回收并且同一个ImageView将用于另一行。

你的列表项 - EventList,现在应该打开或关闭它的铃声,并在getView中适当地设置它。这意味着如果用户录制了第一个项目并设置了铃声,当其他项目重新使用该视图时,它会将其更改为关闭。

答案 1 :(得分:0)

我建议你使用Cursor Loaders并让你的Activity / Fragment实现LoaderCallbacks,使用游标是相当简单的。使用Sqlite数据库或任何其他数据库管理您的EventData,并使用ContentProvider检索您的数据

另外,让EventAdapter扩展CursorAdapter,然后覆盖以下方法: -

public class EventAdapter extends CursorAdapter {

    int layoutResourceId;

    public EventAdapter(Context context, int textViewResourceId) 
    {
        super(context, textViewResourceId, data);
        this.layoutResourceId = textViewResourceId;
    }

    static class EventHolder
    {
       final ImageView icon;
       final ImageView bell;
       final TextView eventName;
       final TextView location;
       final TextView time;
       final TextView coord;
       final int id;
       final int day;

       EventHolder(View view)
        {
           coord = (TextView)view.findViewById(R.id.eventCoor);
           icon = (ImageView)view.findViewById(R.id.icon);
           bell = (ImageView) view.findViewById(R.id.mEventImage);
           eventName = (TextView)view.findViewById(R.id.eventNam);
           location = (TextView)view.findViewById(R.id.eventLoc);
           time = (TextView)view.findViewById(R.id.eventTime);
           id = -1;
           day = -1;
        }
    }
    //Re use the visible views
    @Override
    public void bindView(View view, Context context, Cursor cursor)
    {
        ViewHolder holder = (ViewHolder) view.getTag();
        EventList listItem = cursor.get(position);
        ImageHelper imageHelper = new ImageHelper();
        Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ipl);
        Bitmap newIcon = imageHelper.getRoundedCornerBitmap(icon, 200);
        holder.coord.setText(listItem.coord);
        holder.eventName.setText(listItem.eventName);
        holder.location.setText(listItem.location);
        holder.time.setText(listItem.time);
        holder.icon.setImageBitmap(newIcon);
        holder.id = listItem.id;
        holder.day = listItem.day;

        //Checking Bell State Columnview if it is OFF or ON
        if(cursor.getString(YourActivity.COL_EVENTBELL_IMAGEVIEW_STATE).equals("on"))
        {
            holder.bell.setImageResource(R.drawable.bell_on);
        }
        else
        {
            holder.bell.setImageResource(R.drawable.bell_off);
        }

    }
    //Create new views, all to be visible at once
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent)
    { 
        View view = LayoutInflater.from(context).inflate(layoutResourceId, parent, false);
        EventHolder holder = new EventHolder(view);

        view.setTag(holder);

        return view;
    }
}

在你的Activity / Fragments中你可以使用听众来更新铃声的状态,你的AlarmClick()会是这样的

public void alarmClick()
    {
    Cursor cursor = mEventAdapter.getCursor();
    ContentValues eventValues = new ContentValues();
    String event_bell_state = cursor.getString(YourActivity.COL_EVENT_BELL_IMAGEVIEW_STATE);
    String event_bell_id = cursor.getString(YourActivity.COL_EVENTBELL_ID);

    if(event_bell_state == "on")
    {
        eventValues.put(YourActivity.COL_EVENTBELL_IMAGEVIEW_STATE, "off");
    }
    else
    {
        eventValues.put(YourActivity.COL_EVENTBELL_IMAGEVIEW_STATE, "on");
    }

    String whereClause = YourActivity.COL_EVENTBELL_ID + " = ?";
    String[] selectionArgs = new String[]{String.valueOf(event_bell_id)};

    getActivity().getApplicationContext().getContentResolver().update(EventEntry.CONTENT_URI, eventValues, whereClause, selectionArgs);
    mEventAdapter.notifyDataSetChanged();
    getLoaderManager().restartLoader(EVENTLIST_LOADER, null, this);
    }