2017-02-21 1 views
0

Ich habe Fragment (in FragmentStatePagerAdapter), die globale Variable hat, und in onOptionsItemSelected I verweisen diesen Wert. Es funktioniert zum ersten Mal, wenn ich zurück gehe und auf die gleiche Seite komme und diese globale Variable aktualisiere und jetzt, wenn ich die Werte in onOptionsItemSelected verweise, enthält es die vorherigen Werte und nicht die aktuelle. Ich habe versucht, die "this" -Referenz in onOptionsItemSelected zu drucken, es bezieht sich auf die erste Referenz. Die Werte in anderen Methoden beziehen sich auf den aktualisierten Wert.onOptionsItemSelected von Fragmenten in FragmentStatePagerAdapter hält vorherige diese Referenz

Edit 1: Hinzufügen von Code-Schnipsel

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); 
} 
} 

Die Frage ist mit "mSelectedFieldsId" Variable. Wenn ich dies in onOptionsItemSelected verweise, bezieht es sich auf alte Werte, die gespeichert wurden, und in anderen Methoden bezieht es sich auf den tatsächlichen Wert.

Edit 2: Adapter Code-Schnipsel

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

Fügen Sie das Code-Snippet hinzu.! –

+0

Wenn Sie ein Code-Snippet veröffentlichen, in dem Sie die Variable aktualisieren, wäre es einfacher zu helfen. –

+0

Können Sie den Code auch dort eingeben, wo Sie ihn von Ihrem Adapter an das 'Fragment' übergeben? –

Antwort

0

Sie passieren wahrscheinlich einen Verweis auf Ihre Fragment und die Änderung der Referenz versuchen, sie zu aktualisieren (mit =).

Die Funktionsweise von Variablen besteht darin, dass Ihre Variable eine Speicheradresse enthält, die auf ein Objekt im Speicher verweist. Wenn Sie die Werte ändern möchten und erwarten, dass sich die Änderung in anderen Referenzen widerspiegelt, die an anderer Stelle gespeichert sind, funktioniert die Verwendung von = nicht.

Zum Beispiel, wenn Sie einen ArrayList in Ihrem Adapter und Sie geben es in Ihrem Fragment, wenn Sie mit allen die Werte ersetzen:

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

Es wird in allen anderen Referenzen reflektieren Sie gehalten haben an anderer Stelle als Variablen, aber wenn Sie es wie tun:

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

es ändert die Referenz, diese Variable arrayList zeigt jetzt auf einen völlig anderen Speicherplatz, die ein ganz anderes Objekt enthält. Solche Änderungen werden sich nicht in anderen Referenzen des älteren Objektes widerspiegeln.

+0

Es hat nicht funktioniert. Ich habe das Code-Snippet hinzugefügt. – Velu

0

Es ist einfach. Deklarieren Sie diese globale Variable als statisch. Und verwende diese Variable, wo immer du willst. Lass es mich wissen, wenn das klappt.

+0

Statische Variablen sind nicht überall geeignet. Wenn es an der richtigen Stelle verwendet wird, dient es einem guten Zweck, wenn es an einem falschen Ort verwendet wird, vermasselt Dinge, stellt Bugs vor, die schwer zu finden/zu debuggen sind. –

+0

Wenn Sie mit all Ihren Erklärungen klar sind, dann gibt es keine Möglichkeit, Dinge zu vermasseln. Und es ist auch sicher und einfach zu debuggen. – sivaram

+0

Statische Variablen funktionieren. Aber ich kann nicht alles statisch machen, ich zeige Snackbar auch, es funktioniert zum ersten Mal, aber wenn ich zurück gehe und komme, zeigt es sich nicht, weil es vorheriges "diese" Referenz hält. – Velu

Verwandte Themen