修改
我一直在搜索和阅读很多关于这个主题的内容,但我找不到解决问题的方法。我不知道我做错了什么或设计错误或是什么。
我的活动中有一个片段,这个片段有三种不同的布局出现或消失(这取决于用户做了什么或正在做什么)。另外一个视图组是创建动态添加新的TextViews。当屏幕方向发生变化时,我想保留片段的所有视图,留下像这样看不见的布局,保持所有TextView像它们一样,等等。
我知道当屏幕方向发生变化时,片段和活动的生命周期是如何工作的,但我不知道如何管理它。如何以及从何处恢复仍在内存中的片段,如何恢复视图,并将其返回onCreateView。我放弃了对此的迷惑。
这是xml片段
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true"
android:weightSum="1">
<RelativeLayout
android:id="@+id/top_layout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:padding="8dp"
android:animateLayoutChanges="true"
android:weightSum="1"
android:background="#fc033967">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:fontFamily="sans-serif-condensed"
android:textColor="#ffffff"
android:text="@string/scan_new_code_location"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:layout_gravity="center_vertical"
android:id="@+id/location_textView" />
<LinearLayout
android:id="@+id/new_location_layout"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/new_location_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@android:color/transparent"
android:layout_marginLeft="20dp"
android:src="@drawable/ic_action_new"
android:layout_gravity="center_vertical"/>
<Button
android:id="@+id/boton_nuevaLoc"
android:text="@string/newLocation"
android:fontFamily="sans-serif-condensed"
android:textColor="#ffffff"
android:textSize="15sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:background="@android:color/transparent"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/cancel_ingress_layout"
android:layout_gravity="center_vertical"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true">
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/location_container"
android:layout_width="match_parent"
android:layout_height="40dp"
android:padding="8dp"
android:layout_gravity="center"
android:animateLayoutChanges="true"
android:weightSum="1"
android:background="#fc033967">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="@+id/location_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@android:color/transparent"
android:layout_marginLeft="20dp"
android:src="@android:drawable/ic_menu_mylocation"
android:layout_gravity="center_vertical"/>
<TextView
android:id="@+id/added_location_textView"
android:text="@string/newLocation"
android:fontFamily="sans-serif-condensed"
android:textColor="#ffffff"
android:textSize="15sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:background="@android:color/transparent"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/close_location_container"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true">
<ImageButton
android:id="@+id/close_location_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@android:color/transparent"
android:layout_marginLeft="20dp"
android:src="@android:drawable/ic_menu_send"
android:layout_gravity="center_vertical"/>
</RelativeLayout>
</RelativeLayout>
<LinearLayout android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@android:color/transparent"
android:layout_marginTop="15dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:animateLayoutChanges="true"
android:visibility="invisible"/>
<EditText
android:id="@+id/scan_reader_EditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="500dp"
android:inputType="text"/>
</LinearLayout>
这是代码的一部分
public class LocationFragment extends Fragment {
private static final String TAG = "LocationFragment";
private static final String CSV = ".csv";
private final int scapeChar = KeyEvent.KEYCODE_ENTER;
private final int MODE_FIRST = 0;
private final int SHARED_INTENT = 1;
//Graphics elements
@Bind(R.id.top_layout) RelativeLayout topLayout;
@Bind(R.id.new_location_layout) LinearLayout addLocationLayout;
@Bind(R.id.new_location_image) ImageButton newLocationImage;
@Bind(R.id.boton_nuevaLoc) Button newLocationButton;
@Bind(R.id.cancel_ingress_layout) RelativeLayout cancelScanLayout;
@Bind(R.id.location_textView) TextView locationTextView;
@Bind(R.id.scan_reader_EditText) EditText scanReaderEditText;
@Bind(R.id.container) ViewGroup containerLayout;
@Bind(R.id.location_container) RelativeLayout closeLayout;
@Bind(R.id.added_location_textView) TextView addedLocation;
@Bind(R.id.close_location_image) ImageButton closeImageButton;
static ViewGroup panelIngresarItem;
private boolean scanLocationMode;
private float translation;
private DatabaseManager dbm = DatabaseManager.getInstance();
private String locationCode;
private Location location;
private List<Item> items;
private View.OnClickListener addItemListener;
private String folderPath;
private OnFragmentInteractionListener mListener;
public LocationFragment() {
// Required empty public constructor
}
public static LocationFragment newInstance() {
LocationFragment fragment = new LocationFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_location, container, false);
ButterKnife.bind(this,rootView);
return rootView;
}
public void onViewCreated(View view, Bundle savedInstanceState){
locationTextView.setVisibility(View.GONE);
translation = topLayout.getMeasuredWidth() - addLocationLayout.getMeasuredWidth() +
newLocationButton.getMeasuredWidth();
cancelScanLayout.setOnClickListener(new CloseButtonListener());
cancelScanLayout.setClickable(false);
// Add item listener, for only create one listener
addItemListener = new AddItemListener();
closeImageButton.setOnClickListener(new CloseLocationListener());
panelIngresarItem = (ViewGroup) LayoutInflater.from(this.getActivity()).inflate(
R.layout.new_item_panel,containerLayout,false);
panelIngresarItem.setOnClickListener(addItemListener);
scanLocationMode = true;
closeLayout.setVisibility(View.GONE);
super.onViewCreated(view,savedInstanceState);
}
@Override
public void onResume(){
super.onResume();
containerLayout.removeAllViews();
populateItemList();
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
private void addLocationAnimation(){
RotateAnimation ranim = (RotateAnimation) AnimationUtils.loadAnimation(getContext(),R.anim.rotate_image);
ranim.setDuration(400);
ranim.setInterpolator(new DecelerateInterpolator());
ranim.setFillAfter(true);
ranim.setFillEnabled(true);
translation = topLayout.getMeasuredWidth() - addLocationLayout.getMeasuredWidth() +
newLocationButton.getMeasuredWidth();
newLocationButton.setVisibility(View.GONE);
TranslateAnimation anim =
new TranslateAnimation(0,translation,0,0);
anim.setDuration(400);
anim.setFillAfter(true);
anim.setFillEnabled(true);
newLocationImage.startAnimation(ranim);
addLocationLayout.startAnimation(anim);
cancelScanLayout.setClickable(true);
locationTextView.setVisibility(View.VISIBLE);
enableScanner();
}
private void populateItemList(){
if (location != null) {
containerLayout.removeAllViews();
containerLayout.addView(panelIngresarItem);
items = dbm.getItemListByLocation(location);
for (Item e : items) {
String code = e.getInventoryCode();
addItem(code);
}
}
}
private void callItemEditForm(String code) {
Intent itemFormActivity = new Intent(getActivity(),ItemFormActivity.class);
itemFormActivity.putExtra("Item", code);
itemFormActivity.putExtra("Location",locationCode);
startActivity(itemFormActivity);
}
private void scanLocation(String code){
folderPath = Environment.getExternalStorageDirectory()+
File.separator+getResources().getString(R.string.folder)+File.separator
+ locationCode;
if (dbm.existLocation(code)){
new AlertDialog.Builder(getActivity())
.setTitle(R.string.dialog_tittle)
.setMessage(R.string.dialog_message)
.setPositiveButton(R.string.positive_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
removeHoleDB();
}
})
.setNegativeButton(R.string.negative_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
locationCode = code;
containerLayout.setVisibility(View.VISIBLE);
location = dbm.getLocation(locationCode);
scanLocationMode = false;
addedLocation.setText(locationCode);
topLayout.setVisibility(View.GONE);
closeLayout.setVisibility(View.VISIBLE);
containerLayout.addView(panelIngresarItem);
populateItemList();
}
private void addItem (String code) {
((TextView)panelIngresarItem.findViewById(R.id.new_item_textView)).setText(code);
((ImageView)panelIngresarItem.findViewById(R.id.new_item_image)).setVisibility(View.GONE);
panelIngresarItem.setOnClickListener(null);
//TODO add listener
panelIngresarItem = (ViewGroup) LayoutInflater.from(this.getActivity()).inflate(
R.layout.new_item_panel,containerLayout,false);
panelIngresarItem.setOnClickListener(addItemListener);
containerLayout.addView(panelIngresarItem,0);
}
@OnClick(R.id.boton_nuevaLoc) void addNewLocation(){
addLocationAnimation();
}
class CloseButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
locationTextView.setVisibility(View.GONE);
RotateAnimation ranim = (RotateAnimation) AnimationUtils.loadAnimation(getContext(),R.anim.rotate_image_back);
ranim.setDuration(400);
ranim.setInterpolator(new DecelerateInterpolator());
ranim.setFillAfter(true);
ranim.setFillEnabled(true);
newLocationButton.setVisibility(View.VISIBLE);
TranslateAnimation anim =
new TranslateAnimation(translation,0,0,0);
anim.setDuration(400);
anim.setFillAfter(true);
anim.setFillEnabled(true);
newLocationImage.startAnimation(ranim);
addLocationLayout.startAnimation(anim);
disableScanner();
cancelScanLayout.setClickable(false);
}
}
private class BarcodeEdittextListener implements TextView.OnEditorActionListener {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ( (actionId == EditorInfo.IME_ACTION_DONE) ||
(event.getAction() == KeyEvent.ACTION_DOWN) && event.getKeyCode() == scapeChar ){
String code = v.getText().toString();
if(!code.equals("")) {
if (scanLocationMode)
scanLocation(code);
else {
addItem(code);
callItemEditForm(code);
}
v.setText("");
return true;
}
}
return false;
}
}
class AddItemListener implements View.OnClickListener{
@Override
public void onClick(View v) {
callItemEditForm("N/A");
}
}
class CloseLocationListener implements View.OnClickListener{
@Override
public void onClick(View v) {
deleteAndSend();
/*
new AlertDialog.Builder(getActivity())
.setTitle(R.string.dialog_tittle)
.setMessage(R.string.dialog_message)
.setPositiveButton(R.string.positive_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteAndSend();
}
})
.setNegativeButton(R.string.negative_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
*/
}
}
}
和活动代码
public class MainActivity extends AppCompatActivity {
private FragmentManager fm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.container_fragment, new LocationFragment())
.commit();
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.drawable.ic_launcher_other);
}
}
*************** EDIT ********
行。由于Endzeit,我解决了这个问题。
我需要这样做: 在我的片段中,我创建了一个View变量来引用片段的视图并保留实例。 然后,如果有一个保存的实例,我在onCreateView中返回对我保存的视图的引用。像这样: public class LocationFragment extends Fragment {
private static final String TAG = "LocationFragment";
//Graphics elements
@Bind(R.id.top_layout) RelativeLayout topLayout;
.
.
.
static ViewGroup panelIngresarItem;
**View rootView**;
public LocationFragment() {
// Required empty public constructor
}
public static LocationFragment newInstance() {
LocationFragment fragment = new LocationFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
**setRetainInstance(true)**;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
**if (savedInstanceState == null)** {
**rootView = inflater.inflate(R.layout.fragment_location, container, false);**
ButterKnife.bind(this, rootView);
}
**return rootView;**
}
public void onViewCreated(View view, Bundle savedInstanceState){
if(savedInstanceState == null) {
locationTextView.setVisibility(View.GONE);
translation = topLayout.getMeasuredWidth() - addLocationLayout.getMeasuredWidth() +
newLocationButton.getMeasuredWidth();
cancelScanLayout.setOnClickListener(new CloseButtonListener());
cancelScanLayout.setClickable(false);
// Add item listener, for only create one listener
addItemListener = new AddItemListener();
closeImageButton.setOnClickListener(new CloseLocationListener());
panelIngresarItem = (ViewGroup) LayoutInflater.from(this.getActivity()).inflate(
R.layout.new_item_panel, containerLayout, false);
panelIngresarItem.setOnClickListener(addItemListener);
scanLocationMode = true;
closeLayout.setVisibility(View.GONE);
super.onViewCreated(view, savedInstanceState);
}
}
.
.
.
}
然后在活动中将片段放入FragmentManager并在存在已保存的实例时再次将其取出
public class MainActivity extends AppCompatActivity {
private FragmentManager fm;
public static final String FRAG_LOCATION = "frag_loc";
private LocationFragment fragmentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fm = getSupportFragmentManager();
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
fragmentLocation = new LocationFragment();
} else {
fragmentLocation = (LocationFragment) fm
.getFragment(savedInstanceState,FRAG_LOCATION);
}
fm.beginTransaction()
.replace(R.id.container_fragment, fragmentLocation)
.commit();
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.drawable.ic_launcher_other);
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(fragmentLocation != null) {
getSupportFragmentManager().putFragment(outState,FRAG_LOCATION, fragmentLocation);
}
super.onSaveInstanceState(outState);
}
.
.
.
}
答案 0 :(得分:0)
我想你想要在旋转时保存你的片段和活动的状态。
您必须将片段保存在您的活动onSaveInstanceState()
方法上。
要实现这一点,请将代码更改为:
public static final String TAG_FRAG_LOCATION = "key_frag_loc";
private LocationFragment fragmentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
fm = getSupportFragmentManager();
if(savedInstanceState != null) {
fragmentLocation = (LocationFragment) fragmentManager
.findFragmentByTag(savedInstanceState.getString(TAG_FRAG_LOCATION));
} else {
fragmentLocation = new LocationFragment();
}
fm.beginTransaction()
.replace(R.id.container_fragment, fragmentLocation)
.commit();
...
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(fragmentLocation != null) {
outState.putString(TAG_FRAG_EXAMS, fragmentLocation.getTag());
}
super.onSaveInstanceState(outState);
}