2017-02-21 4 views
0

グローバル変数を持つフラグメント(FragmentStatePagerAdapter内)があり、この値をonOptionsItemSelectedに参照しています。それは最初にうまく動作し、同じページに戻ってこのグローバル変数を更新して、onOptionsItemSelectedの値を参照すると、現在の値ではなく以前の値が保持されます。 "this"リファレンスをonOptionsItemSelectedに印刷しようとしました。これは最初の参照を参照しています。他のメソッドの値は更新された値を参照します。FragmentStatePagerAdapter内のフラグメントのonOptionsItemSelectedは、この参照を前に保持します

編集1:追加のコードスニペット

public class CustomizeFieldFragment extends BaseFragment implements CustomizeFieldListAdapter.IOnSelectCustomizeField { 

private MenuItem mMenuItem; 
private List<String> mSelectedFieldsId; 
private boolean mShowDoneMenu; 

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    menu.clear(); 
    inflater.inflate(R.menu.customize_field_done, menu); 
    mMenuItem = menu.findItem(R.id.action_done); 
    mMenuItem.setVisible(false); 
    super.onCreateOptionsMenu(menu, inflater); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.action_done: 
      updateSelectedFields(); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
    } 
} 

@Override 
public void onSelect(List<String> selectedFieldsId) { 
    if(!selectedFieldsId.isEmpty()){ 
     mSelectedFieldsId = new ArrayList<>(selectedFieldsId); 
     mShowDoneMenu = true; 
    } 
} 

private void updateSelectedFields() { 

    String[] selectionArgs = mSelectedFieldsId.toArray(new String[mSelectedFieldsId.size()]); 
    Uri uri = Contract.DefectFieldEntry.buildDefectFieldUri(baseUrl, domainName, projectName); 
    ContentValues cv = new ContentValues(); 
    cv.put(Contract.DefectFieldEntry.COLUMN_IS_FIELD_SELECTED, true); 
// mContext.getContentResolver().update(uri, cv, null, selectionArgs); 
} 
} 

問題は "mSelectedFieldsId" 変数です。これをonOptionsItemSelectedで参照すると、格納されていた古い値を参照し、他のメソッドでは実際の値を参照します。

編集2:アダプターのコードスニペット

public class CustomizeFieldListAdapter extends RecyclerView.Adapter<CustomizeFieldListAdapter.CustomizeFieldListViewHolder> { 

private static final String TAG = CustomizeFieldListAdapter.class.getSimpleName(); 
private Cursor mCursor; 
private SparseBooleanArray mSelectedItems; 
private IOnSelectCustomizeField onSelectCustomizeField; 
private List<String> mSelectedItemsId; 

public CustomizeFieldListAdapter(IOnSelectCustomizeField iOnSelectCustomizeField){ 
    onSelectCustomizeField = iOnSelectCustomizeField; 
    mSelectedItems = new SparseBooleanArray(); 
    mSelectedItemsId = new ArrayList<>(); 
} 

public class CustomizeFieldListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ 

    TextView tvFieldName; 
    ImageView selectionIcon; 

    public CustomizeFieldListViewHolder(View itemView) { 
     super(itemView); 
     tvFieldName = (TextView) itemView.findViewById(R.id.customize_field_name); 
     selectionIcon = (ImageView) itemView.findViewById(R.id.selection_icon); 
     itemView.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) { 
     int adapterPos = getAdapterPosition(); 
     toggleSelection(adapterPos); 
    } 
} 

@Override 
public CustomizeFieldListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_customize_field, 
      parent, false); 
    return new CustomizeFieldListViewHolder(rootView); 
} 

@Override 
public void onBindViewHolder(CustomizeFieldListViewHolder holder, int position) { 
    mCursor.moveToPosition(position); 
    holder.tvFieldName.setText(mCursor.getString(1)); 
    if(mSelectedItems.get(position, false)) 
     holder.selectionIcon.setImageResource(R.mipmap.select); 
    else 
     holder.selectionIcon.setImageResource(R.mipmap.selection_icon); 
} 

@Override 
public int getItemCount() { 
    return mCursor == null ? 0 : mCursor.getCount(); 
} 

public void swapCursor(Cursor cursor){ 
    mCursor = cursor; 
    notifyDataSetChanged(); 
} 

private void toggleSelection(int position){ 
    mCursor.moveToPosition(position); 
    if(mSelectedItems.get(position, false)){ 
     mSelectedItems.delete(position); 
     mSelectedItemsId.remove(mCursor.getString(0)); 
    } 
    else{ 
     mSelectedItems.put(position, true); 
     mSelectedItemsId.add(mCursor.getString(0)); 
    } 
    onSelectCustomizeField.onSelect(mSelectedItemsId); 
    notifyItemChanged(position); 
} 

public interface IOnSelectCustomizeField { 
    void onSelect(List<String> selectedItemsId); 
} 

}

+2

コードスニペットを追加してください。 –

+0

変数を更新するコードのスニペットを投稿すると、より簡単に役立ちます。 –

+0

アダプターから 'Fragment'に渡すコードを投稿することはできますか? –

答えて

0

あなたはおそらくあなたのFragmentへの参照を渡すと、(=で)それを更新しようとしている参照を変更しています。

変数の動作は、変数がメモリ内のオブジェクトを指すメモリアドレスを保持していることです。その値を変更し、その変更が他の場所に保持されている他の参照に反映されることを期待している場合は、=を使用しても機能しません。例えば

、あなたのアダプタでArrayListを持っているし、あなたとすべての値を交換する場合は、あなたのFragmentでそれを渡す場合:

arrayList.clear(); 
arrayList.add(newValue); 

は、それはあなたが守ってきた他のすべての参照に反映されますあなたのようにそれを行う場合は他の場所で変数として、しかし:

arrayList = new ArrayList<>(); 
arrayList.add(newValue); 

それは参照を変更し、この変数arrayListは今、完全に別のオブジェクトが含まれている完全に異なるメモリ位置、を指します。そのような変更は、他の場所に保管されている古いオブジェクトの他の参照には反映されません。

+0

動作しませんでした。コードスニペットを追加しました。 – Velu

0

簡単です。グローバル変数をstaticとして宣言します。そして、あなたが望む場所でその変数を使用してください。これがうまくいくかどうか私に教えてください。

+0

静的変数はすべての場所で適切ではありません。適切な場所で使用され、良い目的を果たした場合、間違った場所で使用された場合は、物事を混乱させ、見つけにくい/デバッグしにくいバグを導入します。 –

+0

宣言をすべてクリアしていれば、事態を混乱させる可能性はありません。また、安全かつ簡単にデバッグすることができます。 – sivaram

+0

静的変数が機能します。しかし、私はすべてを静的にすることはできません、私はスナックバーも見せています、それは初めてですが、前回の "this"リファレンスを保持しているので表示されません。 – Velu

関連する問題