0

在我的活动中,我的布局是一个列表视图,其中包含复杂的行项目。所以我写了一个类,它是一个自定义的 ArrayAdapter。从我的活动中,我调用了我的 ArrayAdapter,我尝试设置侦听器并获取 imagebutton 点击​​的位置,但它不起作用。位置未设置为正确的值,因为它是 android 需要显示屏幕的最后一个视图的位置。但是我怎样才能获得已单击行的正确位置?我的意思是,例如,如果我的 listView 中有 10 行,然后单击第 5 行,我想要的 toast 信息是用户编号 5 的名称,但 toast 显示位置编号为 10 的行的用户名.. .请帮助我找不到解决方案!谢谢你 !

这是我的arrayadpater的代码:

public class AudioListAdapter extends ArrayAdapter<DonneesListeAudio>  {

// Variables
private Activity activity;
private ArrayList<DonneesListeAudio> DataOfListView;
private static LayoutInflater Inflater = null;
int classPosition=0;

//Constructeur
public AudioListAdapter(Activity activity, int textViewResourceId, ArrayList<DonneesListeAudio> _Liste) {
     super(activity, textViewResourceId, _Liste);
    try {
        this.activity = activity;
        this.DataOfListView = _Liste;
        Inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    } catch (Exception e) {
    }
}

//construction de la vue de l'item
public View getView(int position, View convertView, ViewGroup parent) {
    classPosition = position;
    View ItemView = convertView;
    ViewWrapper Holder;
    try {
        if (convertView == null) {
            ItemView = Inflater.inflate(R.layout.row_liste_audio, null);  /* création de la vue */

            Holder = new ViewWrapper(ItemView);                           /* création d'une instance de wrapper pour conservation des objets de la vue ( textview etc .. )dans le tag de la vue  */

            //  >>>>>>>>>>>>>>>   HERE WAS MY LISTENER BEFORE HASSAN ANSWER
            ImageButton MyImageButton = (ImageButton) Holder.getBase().findViewById(R.drawable.ic_playvert);        /* listner 1 */
            MyImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast ToastCourt = Toast.makeText(getContext(), DataOfListView.get(classPosition).getPseudoUser(), Toast.LENGTH_SHORT);
                    ToastCourt.show();
                }
            });
            ItemView.setTag(Holder);                                      /* sauvegarde du Wrapper de nom Holder dans le tag de la vue crée*/
        } else {
            Holder = (ViewWrapper) ItemView.getTag();                     /* récupération des objets de la vue ( textview etc .. ) via le Wrapper stocké dans le tag */
        }
        chargementDesDonneesDeItem(Holder, position);                     /* chargement des données provenants de MyApplication dans le Wrapper de nom Holder */
    } catch (Exception e) {
    }
    return ItemView;
}

这是我的列表活动,它调用我的数组适配器名称 AudioListAdapter

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    requestWindowFeature(Window.FEATURE_NO_TITLE);    /* suppresion barre de titre */
    setContentView(R.layout.activity_audio);

    //footer (pied de page) de la listView ( à appeler avant l'adapteur )
    View footer = getLayoutInflater().inflate(R.layout.footer, null);
    ListView listView = getListView();
    listView.addFooterView(footer);

    //chargement des données de la premeire page de la listview via LA thread
    chargeListe(0, "PremierePage", "aucun");
    setListAdapter(new AudioListAdapter(this, 0, MyApplication.getMyArrayDonneesListeAudio()));

SOLUCE:这是我的arrayadapter代码,修改了Hassan的解决方案(将setlistener移到IF语句之外)和Rick Falck的解决方案(将位置保存在imageview的标签中)。它有效!太感谢了 !(见下面代码中的注释)

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

    try {
        if (convertView == null) {
            convertView = Inflater.inflate(R.layout.row_liste_audio, null);  /* création de la vue */

            Holder = new ViewWrapper(convertView);                           /* création d'une instance de wrapper pour conservation des objets de la vue ( textview etc .. )dans le tag de la vue  */

            convertView.setTag(Holder);                                      /* sauvegarde du Wrapper de nom Holder dans le tag de la vue crée*/

        } else {

            Holder = (ViewWrapper) convertView.getTag();                     /* récupération des objets de la vue ( textview etc .. ) via le Wrapper stocké dans le tag */


        };


        chargementDesDonneesDeItem(Holder, position);                        /* chargement des données provenants de MyApplication dans le Wrapper de nom Holder */


        ImageView MyImageView = (ImageView)convertView.findViewById(R.id.image_media_play);     /* get instance of the button */
        PositionObject TagPosition = new PositionObject();                                      /* create a new object for tag ( just save position as an INT */
        TagPosition.setPosition(classPosition);                                                 /* set position in the object for tag */
        MyImageView.setTag(TagPosition);                                                        /* save tag with position  */
        MyImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {                                              /* set the listener here to be sure that listener exist even when items convertview are recycled  */
                int idx;
                PositionObject MyPosition = (PositionObject) view.getTag();                     /* get the tag of the view that was click */
                idx=MyPosition.getPosition();                                                   /* get the position of the view in the listitem ! */
                Toast ToastCourt = Toast.makeText(getContext(), DataOfListView.get(idx).getPseudoUser(), Toast.LENGTH_SHORT);
                ToastCourt.show();


            }
        });




    } catch (Exception e) {
            e.getCause();
            e.getLocalizedMessage();
            e.toString();
            e.printStackTrace();


    }
    return convertView;
}
4

3 回答 3

1

只需将以下内容移出 if 语句范围和 else 范围。

您每次都需要这样做:

final int positionForListener = position;
ImageButton MyImageButton = (ImageButton) Holder.getBase().findViewById(R.drawable.ic_playvert);        /* listner 1 */
            MyImageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast ToastCourt = Toast.makeText(getContext(), DataOfListView.get(classPosition).getPseudoUser(), Toast.LENGTH_SHORT);
                    ToastCourt.show();
                    Log.i("position", ""+positionForListener);
                }
            });

基于此逻辑,您需要重新考虑另一行代码以及设置它们的位置。但是,现在这解决了你的问题。

这也有效。为监听器定义一个最终位置变量,然后在监听器中使用它。

于 2013-11-04T20:52:51.407 回答
1

问题是 View.OnClickListener 是 AudioListAdapter 的内部类。适配器在需要绘制项目时调用 getView() 方法。它将具有要绘制的项目的位置。

单击 ImageView 时将调用 onClick() 方法。那时,外部类中的数据将代表最后绘制的项目,而不是单击的项目。因此,classPosition 将是最后绘制的项目,即 #10。

传入 onClick() 的 View 是 ImageView 本身。你需要弄清楚它属于什么项目。我唯一能想到的就是把item的位置放到ImageView.Tag(ImageView.setTag())中。然后在 onClick() 中获得位置 (ImageView.getTag())。

然后,您可以在该位置调用 getItem(posFromTag) 以获取 DataOfListView 中的项目。从那里你可以得到你需要的其他信息。

于 2013-11-04T21:11:38.033 回答
0

在设置将被回收的视图时不要设置监听器。当它被回收时,监听器也会被回收,并且它的关联位置会错误。

各种潜在的解决方案:

  • 不要回收视图。它的效率较低,但是如果您每次都膨胀并填充一个新视图,那么您不会遇到来自回收视图的数据被回收的问题。
  • 使用AdapterView.setOnItemClickListener而不是按钮。整个列表项都是可点击的,而不仅仅是按钮,并且会自动处理正确的位置。
  • 将侦听器设置为设置回收视图的一部分,而不是新视图。
于 2013-11-04T20:55:14.030 回答