2

私のアプリには、アイテムが画像、テキスト、および線形レイアウトで構成されるリストビューがあります。カスタム アダプター クラスに onClickListener を実装したいと考えています。リスト内の項目がクリックされると、linearlayout の可視性が Visible または Gone に設定されます。問題は次のとおりです。リスト内のアイテムをクリックしてリストをスクロールすると、他のアイテムの線形レイアウトが表示されます(ビューのリサイクルとすべてのために、私は知っています)。

この問題をどのように解決し、クリックしたアイテムの線形レイアウトのみがスクロール後に必要な可視性を得ることができますか?

onClick イベントなしで、私のアダプター コードは以下のとおりです。

public class myadapter extends ArrayAdapter<lwicon> {

    Context context;
    lwicon[] iteminarow;
    public myadapter(Context context,lwicon[] iteminarow)
    {
        super(context, R.layout.listitem, iteminarow);
        this.context=context;
        this.iteminarow=iteminarow;
    }

    static class ViewHolder
    {
        public ImageView imageview;
        public TextView textview;
        public LinearLayout linearlayout;
    }

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

        ViewHolder holder = null;

        if(convertView==null)
        {

         LayoutInflater LI= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

         convertView= LI.inflate(R.layout.listitem, parent, false);
         holder = new ViewHolder();
         holder.textview=(TextView)convertView.findViewById(R.id.unitname);
         holder.imageview=(ImageView)convertView.findViewById(R.id.image);
         holder.linearlayout=(LinearLayout)convertView.findViewById(R.id.invisiblablesubitem);

         convertView.setTag(holder);
        }

        else
        {
            holder=(ViewHolder)convertView.getTag();

        }

        holder.imageview.setImageResource(iteminarow[position].icon);
        holder.textview.setText(iteminarow[position].unitname);

        return convertView;
    }
}

リスト項目のレイアウトは次のとおりです。

<?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" >

    <LinearLayout android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView android:id="@+id/image"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"/>
        <TextView  android:id="@+id/unitname"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/invisiblablesubitem"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:orientation="vertical"
        android:visibility="gone">
        <TextView android:id="@+id/tt"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="HELLO"/>
    </LinearLayout>
</LinearLayout>

更新: Rishabh.CreatioSoft の回答に関して、アダプターを更新しましたが、リストビューの項目をクリックするたびにアプリがクラッシュします。助けてください...

public class myadapter extends ArrayAdapter<lwicon> {

    Context context;
    lwicon[] iteminarow;
    private LayoutInflater inflater;
    public myadapter(Context context,lwicon[] iteminarow)
    {
        super(context, R.layout.listitem, iteminarow);
        this.context=context;
        this.iteminarow=iteminarow;
         inflater = LayoutInflater.from(context);
    }

    static class ViewHolder
    {
        public ImageView imageview;
        public TextView textview;
        public LinearLayout linearlayout;
    }

    @Override
    public View getView(int position,View convertView,ViewGroup parent)

    {
        lwicon item = (lwicon)this.getItem(position);

        ImageView imageView;
        TextView textView;
        LinearLayout linearLayout;


        if(convertView==null)
        {

         convertView=inflater.inflate(R.layout.listitem, parent,false);
         textView=(TextView)convertView.findViewById(R.id.unitname);
         imageView=(ImageView)convertView.findViewById(R.id.image);
         linearLayout=(LinearLayout)convertView.findViewById(R.id.invisiblablesubitem);

         ViewHolder holder = new ViewHolder();
         holder.imageview=imageView;
         holder.textview=textView;
         holder.linearlayout=linearLayout;
         convertView.setTag(holder);

         convertView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    lwicon item1 = (lwicon)v.getTag();
                    item1.isLLvisible=true;
                }
            });

        }

        else
        {
            ViewHolder holder2=(ViewHolder)convertView.getTag();
            textView=holder2.textview;
            imageView=holder2.imageview;
            linearLayout=holder2.linearlayout;

        }

        linearLayout.setTag(item);

        imageView.setImageResource(item.icon);
        textView.setText(item.unitname);
        if(item.isLLvisible==true)
            linearLayout.setVisibility(View.VISIBLE);



        return convertView;
    }
}
4

3 に答える 3

2

CaseyB と Rishabh.CreatioSoft のおかげで、私が抱えていた問題を解決する方法を見つけました。問題はリストをスクロールした後だったので、リストのアイテムの線形レイアウトが台無しになりました。addapter 用に実装したコードは次のとおりです。

public class myadapter extends ArrayAdapter<lwicon> {

    Context context;
    public lwicon[] iteminarow;
    public myadapter(Context context,lwicon[] iteminarow)
    {
        super(context, R.layout.listitem, iteminarow);
        this.context=context;
        this.iteminarow=iteminarow;
    }
// the ViewHolder class that saves the row's states, acts as Tag
static class ViewHolder
{
    ImageView img;
    TextView txt;
    LinearLayout line;
    int visibility;
    public ViewHolder(ImageView img,TextView txt,LinearLayout line,int visibility)
    {
        this.img=img;
        this.txt=txt;
        this.line=line;
        this.visibility=visibility;
    }


}

    @Override
    public View getView(int position,View convertView,ViewGroup parent)

    {     // get item from ArrayAdapter and set viarables for the row to be inflated
        lwicon item = (lwicon) this.getItem(position);
        ImageView image;
        TextView text;
        LinearLayout linear;
        int visibility=View.GONE;

        if(convertView==null)
        {
        LayoutInflater LI= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         convertView=LI.inflate(R.layout.listitem, parent,false);
         text=(TextView)convertView.findViewById(R.id.unitname);
         image=(ImageView)convertView.findViewById(R.id.image);
         linear=(LinearLayout)convertView.findViewById(R.id.invisiblablesubitem);
             //row is inflated, we just tag it with the ViewHolder, we add the inflated
            //ImageView,TextView,LinearLayout and Visibility stat to the tagged ViewHolder
         convertView.setTag(new ViewHolder(image, text, linear,visibility));

        }


        else
        {        //recover the tagged ViewHolder and it's items
            ViewHolder holder = (ViewHolder) convertView.getTag();
            text = holder.txt;
            image= holder.img;
            linear=holder.line;
            visibility=holder.visibility;
        }


        image.setImageResource(item.icon);
        text.setText(item.unitname);
        linear.setVisibility(item.visibility);


        return convertView;
    }
}

lwicon クラスは次のとおりです。

public class lwicon {
public int icon;
public String unitname;
public LinearLayout linearLayout;
public int visibility=View.GONE;
public lwicon(){
}
public lwicon(int imageid,String text)
{
    icon = imageid;
    unitname=text;

}
public void toggleVisibility()
{
    if(this.visibility==View.GONE)
        this.visibility=View.VISIBLE;
    else if(this.visibility==View.VISIBLE)
        this.visibility=View.GONE;
    else this.visibility=View.VISIBLE;
}

}

そして、リストのアダプターを設定した後、MainAvtivity クラスに OnItemClickListener を実装しました。

lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> adapter, View view, int position,
                    long id) {
                // TODO Auto-generated method stub
             // getting the item that was clicked in ArrayAdapter<lwicon>
                lwicon item=(lwicon)adapter.getAdapter().getItem(position);
                item.toggleVisibility();
             // recovering the tag (that is the viewholder)from convertView 
             //(view parameter here refers to convertView in getView method)
                ViewHolder holder = (ViewHolder)view.getTag();
                holder.line.setVisibility(item.visibility);
            }
        });

また、linearlayout サブアイテムを持つリストビューのアイテムは、スクロール後に親ビューであることを忘れません。

PS: 皆さん、このテーマに関するチュートリアルはほとんどありません...私は思う

于 2012-09-20T10:37:34.263 に答える
1

こんにちは、BaseAdapter の代わりに Custome Adapter を使用してこの問題を解決できます。このリンクをフォローしてくださいチュートリアル

于 2012-09-19T15:37:40.800 に答える
0

あなたがする必要があるのは、非表示/表示状態をlwiconアイテムに保存し、ビューを再作成するときにそれを確認することですgetView().

于 2012-09-19T15:29:07.870 に答える