There is a simple project (full listing below).
In project,
There is an Activity with ListView. Each element of the list is a button - clicking on which brings up the context menu.
in the MainActivity class there is a tagButton field that remembers the position of the element whose button was pressed.
The adapter is custom, menu items are drawn inside the adapter, and the Tag field of the button is assigned the position of a specific item in the list.
When you rotate the screen, the adapter is saved with a fragment
Before the screen rotates, everything works (pressing the button -> saving the position in the tagButton -> menu display -> getting the correct tagButton).
But if you turn the screen, it turns out something incomprehensible to me: pressing the button -> saving the correct position in tagButton -> displaying the menu -> getting the wrong tagButton ?!
What happens between “storing the correct position in the tagButton” and “getting the wrong tagButton”?
Ps. If you wrap the tagButton into a simple class and change / get the value using the setter / getter and at the same time save an instance of the class through a fragment (when you turn the screen), then everything is fine.
Pps. Algorithm for receiving errors:
- Run the application.
- Press any button (for example, 3), a menu appears. Logs: Tag before: 3
- Select a menu item. In Tag after logs: 3
- Turn over the screen.
- Press any button (for example, 2), a menu appears. Logs: Tag before: 2
- Select a menu item. Tag after logs: -1
MainActivity code:
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ListView; import layout.SaveFragment; public class MainActivity extends AppCompatActivity { int tagButton = -1; LvAdapter adapter; SaveFragment saveStateFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); saveStateFragment = (SaveFragment) getSupportFragmentManager().findFragmentByTag("SAVE"); if (saveStateFragment != null) { adapter = saveStateFragment.getAdapter(); } else { saveStateFragment = new SaveFragment(); getSupportFragmentManager() .beginTransaction() .add(saveStateFragment, "SAVE") .commit(); adapter = new LvAdapter(this); } tagButton = -1; ((ListView) findViewById(R.id.lv1)).setAdapter(adapter); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { tagButton = (int) ((Button) v).getTag(); Log.d("err", "Tag before: " + String.valueOf(tagButton)); menu.add("Получить Tag"); } @Override public boolean onContextItemSelected(MenuItem item) { Log.d("err", "Tag after: " + String.valueOf(tagButton)); return super.onContextItemSelected(item); } @Override protected void onPause() { saveStateFragment.setAdapter(adapter); super.onPause(); } }
Adapter code:
import android.app.Activity; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; public class LvAdapter extends BaseAdapter { int count = 100; Context ctx; LayoutInflater lInflater; public LvAdapter (Context context) { ctx = context; lInflater = (LayoutInflater) ctx .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return count; } @Override public Integer getItem(int i) { return i; } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View convertView, ViewGroup viewGroup) { View view = convertView; if (view == null) { view = lInflater.inflate(R.layout.item, viewGroup, false); } final Button btn = (Button) view.findViewById(R.id.btn); btn.setText(String.valueOf(i)); btn.setTag(i); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Activity activity = (Activity) ctx; activity.registerForContextMenu(btn); activity.openContextMenu(btn); } }); return view; } }
Fragment code:
import android.os.Bundle; import android.support.v4.app.Fragment; import biz.temp.LvAdapter; public class SaveFragment extends Fragment { LvAdapter adapter; public LvAdapter getAdapter() { return adapter; } public void setAdapter(LvAdapter adapter) { this.adapter = adapter; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } }
Activity Markup:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <ListView android:id="@+id/lv1" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
The layout of the list item:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/btn"/> </LinearLayout>
RecyclerView
you simply would have had enough ofViewHolder
get a button from each element, and tag it there, without forwarding and re-assigning links. - Silento