0

onListItemClick で、クリックしたアイテムの背景を変更したいのですが、これは私のコードです:

public void onListItemClick(ListView parent, View v, int position, long id){

    if (position != previous_position){
        v.setBackgroundResource(R.drawable.category_clicked_item_bg);
        if (previous_category != null)
            previous_category.setBackgroundResource(R.drawable.category_item_bg);
        previous_category = v;
        previous_position = position;
    }
}

previous_category と previous_position は保護された変数です。

問題は、項目をクリックすると、リスト内の複数の項目が強調表示されることです (具体的には 1 つまたは 2 つ)。リストには20行あります。中央の1つをクリックすると、1つだけが強調表示され、最初または最後の行をクリックすると、反対側の他の行が間隔13行で強調表示されます(おそらく中央の行を押す理由ですドン2 番目にハイライトしないでください)。

クリックした行を 1 行だけ強調表示するリストが必要ですが、何が問題ですか?

追加コード

それが役立つ場合は、ListView アダプター クラスも示します。

package domehotel.guestbook.page.category;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import domehotel.guestbook.R;

public class CategoryAdapter extends ArrayAdapter<CategoryItem>{

Context context; 
int layoutResourceId;    
CategoryItem data[] = null;

public CategoryAdapter(Context context, int layoutResourceId, CategoryItem[] data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    CategoryHolder holder = null;

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

        holder = new CategoryHolder();
        holder.category_name = (TextView)row.findViewById(R.id.category_name);

        row.setTag(holder);
    }
    else
    {
        holder = (CategoryHolder)row.getTag();
    }

    CategoryItem category = data[position];
    holder.category_name.setText(category.category_name);

    return row;
}

static class CategoryHolder
{
    TextView category_name;
}
}
4

3 に答える 3

1

ListView 行ビュー オブジェクトは複数の行ごとに再利用されるため、行ビューでアクティブな行に関する情報を保持することはお勧めできません。この情報をアダプター (私の場合は CategoryAdapter) に保持することをお勧めします。タイプ CategoryItem のデータ配列は、次のクラスのオブジェクトを保持します。

public class CategoryItem {

    public String category_name;
    public Boolean is_active = false;

    public CategoryItem(){
        super();
    }

    public CategoryItem(String category_name){
        super();
        this.category_name = category_name.toUpperCase();
    }
}

また、アダプターは、onView メソッドでビュー項目を再描画するときに、現在の行がアクティブかどうかを確認します。

if (category.is_active)
    row.setBackgroundResource(activeBgDrawable);
else
    row.setBackgroundResource(inactiveBgDrawable);

したがって、アイテムをクリックすると、CategoryItem の is_active プロパティを true に設定し、前にクリックした is_active プロパティを false に設定します。

if (position != previous_position){
    CategoryAdapter adapter = (CategoryAdapter)parent.getAdapter();
    CategoryItem current_item = adapter.getItem(position);
    current_item.is_active = true;
    if (previous_position != -1){
        CategoryItem previous_item = adapter.getItem(previous_position);
                    previous_item.is_active = false;
        }
    previous_position = position;
    adapter.notifyDataSetChanged();
}

ビュー オブジェクトの背景の設定が機能しないのはなぜですか? ListView が表示できるよりも多くの ListView 項目を含む ListView がある場合、リストはスクロール可能になり、たとえば、ListView を下にスクロールすると、上部の項目が表示されている部分からスライドすると、この行の ListView 項目 View オブジェクト一番下に表示される次の行に再利用されます。したがって、上の行がビューオブジェクトの背景を変更したものである場合、それが消えると、下の行が上の行で再描画され、その背景を持つビューオブジェクトが表示されるため、2 つの色付きの行が表示されることがあります。

于 2012-08-24T12:14:55.420 に答える
0

実際、ビューを再利用しています。getView は、convertView という名前のビューを 2 番目のパラメーターとして受け取ります。ListView は、インスタンス化 (膨張) されていますが、現時点では表示されていない古いビュー項目 (存在する場合) を使用してこのメ​​ソッドを呼び出します。あなたの覚醒剤。onListItemClick は、これらのビューのいずれかの背景を設定するようになりましたが、このビューは後で別の行に再利用され、背景のリセットは行われません。

考えられる解決策:

  1. クリックリスナーは、クリックされた位置の背景色またはクリックされたフラグのみを保存し、問題のビュー(行)に再レンダリングを要求する必要があります(状態を保存してから背景を直接設定することもできます)。

  2. getView(..) メソッドは常に、その位置の保存された色/状態に従ってビューの背景色を設定する必要があります。クリックとしてマークされていない位置に通常の背景を設定するか、クリック リスナーによってクリックされたとしてマークされた位置に別の背景を設定します。

于 2012-08-24T10:46:39.260 に答える
0

OnItemClick で次のコードを試してください

public void onListItemClick(ListView parent, View v, int position, long id){

if (position != previous_position){
    v.setBackgroundResource(R.drawable.category_clicked_item_bg);   
    Object view = parent.getTag();
    if(view!=null){
       // typecasting the Object to View
       ((View)view).setBackgroundResource(R.drawable.category_item_bg);
    }
    previous_position = position;
    parent.setTag(v);
}
}

これで問題が解決することを願っています。

于 2012-08-24T10:46:42.860 に答える