2017-02-21 21 views
0

私はListViewを持ち、各ListItemにはクリックされたときに2つのボタンを持つオーバーフローメニューを表示するIm​​ageButtonがあります。 TrackedRunというオブジェクトから継承したカスタムArrayAdapterを使用しています。私はオーバーフローメニューを介してクリックされたListItemに対応するTrackedRunオブジェクトへの参照を取得したいと思います。ボタンをクリックすると、Androidがリスト項目の位置を取得します

これは私のアダプタである(ただ、関連するコードを含む):

public class HistoryListItemAdapter extends ArrayAdapter<TrackedRun> { 

public interface OnOverflowButtonListener { 
    void onDeleteClick(int id); 
    void onEditClick(int id); 
} 


private Context context; 
private TrackedRun currentItem; 
private View rootView; 
private OnOverflowButtonListener listener; 
private int position; 

public HistoryListItemAdapter(Context context, ArrayList<TrackedRun> items, 
           HistoryFragment historyFragment, OnOverflowButtonListener listener){ 
    super(context, 0, items); 
    this.context = context; 
    this.listener = listener; 
} 

@NonNull 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) getContext() 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    rootView = convertView; 
    currentItem = getItem(position); 
    this.position = position; 

    if (null == rootView) { 
     rootView = inflater.inflate(
       R.layout.history_list_item, 
       parent, 
       false); 
    } 
    setOverflowMenu(); 

    return rootView; 
} 

private void setOverflowMenu(){ 
    final ImageButton button = (ImageButton) rootView.findViewById(R.id.overflow_icon); 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(final View v) { 

      final PopupMenu menu = new PopupMenu(getContext(), button); 
      menu.getMenuInflater().inflate(R.menu.list_item_overflow, menu.getMenu()); 
      menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { 
       @Override 
       public boolean onMenuItemClick(MenuItem item) { 

        switch (item.getItemId()){ 

         case R.id.edit_button : 
          listener.onEditClick(currentItem.getId()); 
          break; 

         case R.id.delete_button : 
          listener.onDeleteClick(currentItem.getId()); 
          break; 
        } 
        return true; 
       } 
      }); 
      menu.show(); 
     } 
    }); 
} 

} 

そして、これは私がListViewコントロール(関連するコード)を初期化フラグメントである:

public class HistoryFragment extends Fragment { 

private View rootView; 
private HistoryListItemAdapter adapter; 
private ListView listView; 

public HistoryFragment(){ 
    //Required empty constructor. 
} 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    rootView = inflater.inflate(R.layout.fragment_history, container, false); 
    initListView(); 

    return rootView; 
} 

private void initListView(){ 
    listView = (ListView) rootView.findViewById(R.id.history_listview); 
    ArrayList<TrackedRun> trackedRuns = new DatabaseHandler(getContext()).getAllTrackedRuns(); 
    adapter = new HistoryListItemAdapter(getContext(), trackedRuns, this, new HistoryListItemAdapter.OnOverflowButtonListener() { 
     @Override 
     public void onDeleteClick(int id) { 
      System.out.println(id); 
     } 

     @Override 
     public void onEditClick(int id) { 
      System.out.println(id); 
     } 
    }); 
    listView.setAdapter(adapter); 
    listView.setEmptyView(rootView.findViewById(R.id.empty_view)); 

} 

private void loadRecords() { 
    //Gets records from database, and reloads ListView with new records. 
} 

} 

私はonEditClickを呼び出すとし、私のアダプタのonDeleteClick、currentItemからのidは、常に最後に追加されたListItemのIDであり、クリックされたものではありません。正しいIDを取得するために、クリックされたListItemに対応するTrackedRunオブジェクトを取得するにはどうすればよいですか?

答えて

2

あなたは、各オーバーフローメニューを初期化するとき、あなたはリストビューを膨らませるとき

+0

ありがとうございました!あなたが私になぜこれが起こるのか説明することができますか?私の推測では、新しいListItemが追加されるたびにgetViewメソッドが実行され、コードは最後の項目で終了するまで上書きされます。 – TobiasP

+1

@TobiasPあなたは正しいです。リストビューの仕組みを理解する。 getViewメソッド内にログを追加することをお勧めします。再度アプリケーションを実行して、logcatを確認してください。私はあなたの問題がなぜ解決するのか知っていると思います –

1

getView方法がexcutedされます。この

private void setOverflowMenu(final TrackedRun currentItem){ 
... 
} 

のように、現在のアイテムを渡し、ローカル変数にグローバル変数からprivate TrackedRun currentItemを変更する必要がありますgetCount()回。あなたのListViewが膨張完了したら、currentItemは最後です。私の提案は:

private void setOverflowMenu(final int position){ 
    ... 
} 

あなたの配列をすでにActivityに持っているので、位置を使用する方が簡単です。

関連する問題