在我的活动中,我的布局是一个列表视图,包含复杂的行项。所以我写了一个自定义ArrayAdapter的类。从我的活动,我调用我的ArrayAdapter,我试图设置 监听器并获取图像按钮单击的位置,但它不起作用。 位置未设置为正确的值,因为它是android需要显示屏幕的最后一个视图的位置。但是我如何才能获得已单击的行的正确位置? 我的意思是,例如,如果我在listView中有10行,并且我单击行项目5,我想要的用于吐司的信息是用户编号5的名称,但是吐司显示位置编号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;
}
这是我的listactivity,它调用我的arrayadapter名称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:这是我使用Hassan解决方案修改的arrayadapter代码(在IF语句之外移动setlistener)和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;
}
答案 0 :(得分: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);
}
});
基于这种逻辑,您需要重新考虑其他代码行以及设置它们的位置。 但是,现在这解决了你的问题。
这也有效。为侦听器定义最终位置var,然后在侦听器中使用它。
答案 1 :(得分:1)
问题是View.OnClickListener是AudioListAdapter的内部类。适配器在需要绘制项时调用getView()方法。它将具有要绘制的项目的位置。
单击ImageView时将调用onClick()方法。那时,外部类中的数据将代表最后绘制的项目,而不是单击的项目。因此,classPosition将是最后绘制的项目,即#10。
传递给onClick()的视图是ImageView本身。你需要弄清楚它属于哪个项目。我唯一能想到的是将项目的位置放入ImageView.Tag(ImageView.setTag())。然后在onClick()中获取位置(ImageView.getTag())。
然后你可以在该位置调用getItem(posFromTag)来获取DataOfListView中的项目。从那里你可以得到你需要的其他信息。
答案 2 :(得分:0)
设置要回收的视图时,请勿设置侦听器。当它被回收时,听众也会如此,它将与错误的位置相关联。
各种潜在的解决方案:
AdapterView.setOnItemClickListener
代替按钮。整个列表项是可点击的,而不仅仅是按钮,自动处理正确的位置。