0

在我的活動中,我的佈局是一個列表視圖,其中包含複雜的行項目。所以我寫了一個類,這是一個自定義ArrayAdapter。從我的活動中,我打電話給我的ArrayAdapter,並試圖設置 偵聽器並獲取imagebutton點擊的位置,但它不起作用。 位置沒有設置在正確的值,因爲它是Android需要顯示屏幕的最後一個視圖的位置。但我怎麼才能得到已被點擊的行的正確位置? 我的意思是,例如,如果我在我的listView中有10行,並且單擊行項目5,我想要的烤麪包的信息是用戶編號5的名稱,但烤麪包機顯示位置編號爲10的行的用戶名。 .. 請幫我找不到解決方案!謝謝 !Android:如何設置監聽器並獲取imagebutton在自定義適配器中的點擊位置

這裏是我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:這是我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

有點哈桑知道我有我的列表視圖的所有項目的聽衆,謝謝你的答案。問題是,當android需要在屏幕上繪製項目時,監聽器被設置,但是當我點擊我的列表視圖時,android來執行監聽器的代碼,在這一刻,我只有我的imagebutton和im無法檢索這個視圖在我的列表視圖中的位置。所以還是不行。我能怎麼做 ?是否有可能檢索這個圖像buttonview的父視圖?事實上,我只需要在列表中的位置... –

+0

現在就可以工作(請參閱上面的解決方案)。我已經使用哈桑和瑞克的解決方案。非常感謝你 ! –

回答

1

簡單地採取下列出的if語句範圍和其他範圍之後。

你需要做的,每次:

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,然後在偵聽器中使用它。

+0

謝謝哈桑 –

0

設置將要回收的視圖時,不要設置偵聽器。當它被循環使用時,聽衆也會被關閉,並且它會有與之相關的錯誤位置。

各種可能的解決方案:

  • 不回收的意見。效率較低,但如果每次都膨脹並填充新視圖,則不會因循環視圖中的數據出現問題。使用AdapterView.setOnItemClickListener而不是按鈕。整個列表項是可點擊的,而不僅僅是按鈕,並且正確的位置被自動處理。
  • 將偵聽器設置爲設置循環視圖的一部分,而不是新的視圖。
1

的問題是,View.OnClickListener是內類AudioListAdapter。 getView()方法在需要繪製項目時由適配器調用。它將具有該項目的位置繪製。

onClick()方法將在單擊ImageView時被調用。那時,外部類中的數據將代表最後繪製的項目,而不是單擊的項目。所以,classPosition將是最後一個繪製的項目,即#10。

傳遞給onClick()的視圖是ImageView本身。你需要弄清楚它屬於哪個項目。我唯一能想到的就是將項目的位置放到ImageView.Tag(ImageView.setTag())中。然後在onClick()中獲得位置(ImageView.getTag())。

然後,您可以在該位置調用getItem(posFromTag)以獲取DataOfListView中的項目。從那裏你可以得到你需要的其他信息。

+0

thick你瑞克它的工作原理 –

相關問題