2016-06-13 92 views
0

我有一個帶有Tablayout的MainActivity承載的PhotosFrgament類。 PhotoFragment允許用戶從自定義圖庫中選擇多張照片並將其顯示在ListView中。但是在屏幕旋轉時,PhotosFragment被清除。根據我的理解,我應該使用setRetainInstance(true),但似乎不起作用,有什麼想法?配置更改時保留片段

public class MainActivity extends AppCompatActivity { 

private TabLayout tabLayout; 
private ViewPager viewPager; 
private static int TAB_ITEMS=1; 

@Override 
protected void onCreate(Bundle savedInstanceState){ 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    // Set a Toolbar to replace the ActionBar. 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    setTitle(R.string.photos); 

    tabLayout = (TabLayout)findViewById(R.id.tabs); 
    viewPager = (ViewPager)findViewById(R.id.viewpager); 

    /** 
    *Set an Apater for the View Pager 
    */ 
    viewPager.setAdapter(new MyAdapter(getSupportFragmentManager())); 

    /** 
    * Now , this is a workaround , 
    * The setupWithViewPager dose't works without the runnable . 
    * Maybe a Support Library Bug . 
    */ 

    tabLayout.post(new Runnable() { 
     @Override 
     public void run() { 
      tabLayout.setupWithViewPager(viewPager); 
     } 
    }); 

    //check for parent activity defined in the manifest before 
    //displaying caret 
    if(NavUtils.getParentActivityName(this) != null) 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 



}//end method onCreate 


class MyAdapter extends FragmentPagerAdapter { 

    public MyAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    /** 
    * Return fragment with respect to Position . 
    */ 

    @Override 
    public Fragment getItem(int position) 
    { 
     switch (position){ 
      case 0 : 
       return new Photos(); 


     } 
     return null; 
    } 

    @Override 
    public int getCount() { 

     return TAB_ITEMS; 

    } 

    /** 
    * This method returns the title of the tab according to the position. 
    */ 

    @Override 
    public CharSequence getPageTitle(int position) { 

     switch (position){ 
      case 0 : 
       return "Photos"; 



     } 
     return null; 
    } 


}//end class MyAdapter 


@Override 
public boolean onOptionsItemSelected(MenuItem item){ 

    switch(item.getItemId()){ 

     case android.R.id.home: 
      //if there is a parent activity declared in the manifest 
      //then navigate to the parent activity 
      if(NavUtils.getParentActivityName(this) != null) 
       NavUtils.navigateUpFromSameTask(this); 

      return true; 
     default: 
      return super.onOptionsItemSelected(item);//implement superclass 
     //implementation 
    } 

}//end method onOptionsItemSelected 



}//end class MainActivity 


public class PhotosFragment extends ListFragment { 


private static final int SELECT_MULTIPLE_PHOTOS = 0;//Set Intent Id 
public static final String CustomGalleryIntentKey = "ImageArray";//Set Intent Key Value 
private static final String TAG = "PhotosFragment"; 

private EditText mImagesDescriptionEditText; 
private RelativeLayout mImagesDescriptionRelativeLayout; 
private ListView mSelectedImagesListView; 


@Override 
public void onCreate(Bundle savedInstanceState){ 

    super.onCreate(savedInstanceState); 
    setRetainInstance(true);//retain fragment on configuration changes 
    setHasOptionsMenu(true);//fragment will be implementing menu call backs 
    //on behalf of activity 

}//end method onCreate 

@Override 
public void onActivityCreated(Bundle savedInstanceState){ 
    super.onActivityCreated(savedInstanceState); 
    setRetainInstance(true); 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup parent 
     ,Bundle savedInstanceState){ 

    View v = inflater.inflate(R.layout.fragment_photos, parent,false); 

    mSelectedImagesListView = (ListView)v.findViewById(android.R.id.list); 
    mImagesDescriptionRelativeLayout = (RelativeLayout) 
      v.findViewById(R.id.photos_descriptionRelativeLayout); 
    mImagesDescriptionEditText = (EditText)v.findViewById(R.id.photos_descriptionEditText); 
    mImagesDescriptionRelativeLayout.setVisibility(View.INVISIBLE); 



    return v; 
}//end method onCreateView 


@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ 

    super.onCreateOptionsMenu(menu,inflater); 
    inflater.inflate(R.menu.fragment_photos, menu); 
}//end method onCreateOptionsMenu 

@Override 
public boolean onOptionsItemSelected(MenuItem item){ 

    switch(item.getItemId()){ 

     case R.id.menu_item_upload_photo: 

      //Start Custom Gallery Activity by passing intent id 
      Intent i = new Intent(getActivity(),CustomGalleryActivity.class); 
      startActivityForResult(i,SELECT_MULTIPLE_PHOTOS); 

      return true; 

     default: 
      return super.onOptionsItemSelected(item); 
    }//end switch 
}//end onOptionsItemSelected 

@Override 
public void onActivityResult(int requestCode, int resultCode, 
           Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if(resultCode != Activity.RESULT_OK) 
     return; 

    if(requestCode == SELECT_MULTIPLE_PHOTOS){ 

     String imagesArray = data.getStringExtra(CustomGalleryIntentKey);//get Intent data 

     //Convert string array into List by splitting by ',' and substring after '[' and before ']' 
     List<String> selectedImages = Arrays.asList(imagesArray.substring(1, imagesArray.length() - 1).split(", ")); 
     loadSelectedImagesListView(new ArrayList<String>(selectedImages)); 

    } 
} 


private void loadSelectedImagesListView(ArrayList<String> imagesArray){ 

    try{ 
     mImagesDescriptionRelativeLayout.setVisibility(View.VISIBLE); 

    }catch (Throwable e){ 
     e.printStackTrace(); 
    } 

    SelectedImagesAdapter adapter = new SelectedImagesAdapter(imagesArray); 
    mSelectedImagesListView.setAdapter(adapter); 


} 

//custom adapter as inner class 
private class SelectedImagesAdapter extends ArrayAdapter<String>{ 

    public SelectedImagesAdapter(ArrayList<String> imagesArray){ 

     super(getActivity(),0,imagesArray); 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent){ 

     //if we arent given a view inflate one 
     //if there's no recycled view passed in inflate one 
     if(convertView == null) 
      convertView = getActivity() 
        .getLayoutInflater() 
        .inflate(R.layout.list_item_selected_image, null); 

     //configure the view for this image 
     String imagePath = getItem(position); 

     ImageView imageView = (ImageView)convertView.findViewById(R.id.selected_imageImageView); 
     Bitmap bm = BitmapFactory.decodeFile(imagePath); 

     //get the screen width at run time 
     int screenWidth = DeviceDimensionsHelper.getDisplayWidth(getActivity()); 

     //load resized bitmap into an ImageView 
     imageView.setImageBitmap(BitmapScaler.scaleToFitWidth(bm, screenWidth)); 

     EditText caption = (EditText)convertView.findViewById(R.id.selected_imageCaption); 


     return convertView;//return view object to the list view 

    } 
}//end private class ImagesAdapter 


}//end class PhotosFragment 
+1

有方法_onSavedInstance()_保存數據 – Piyush

+0

看看這個答案: http://stackoverflow.com/questions/21012245/fragments-disappear-when-rotated – GPortas

+0

@Piyush古普塔。感謝人工作。在方法onSavedInstanceState中保存返回圖像的ArrayList。在方法onCreateView中檢索保存的包可以正常工作 – theTypan

回答

1

解決了這個問題。我使用onSaveInstanceSate,然後在方法onCreateView中檢索保存的包。

@Override 
public void onSaveInstanceState(Bundle savedInstanceState){ 

    super.onSaveInstanceState(savedInstanceState); 
    savedInstanceState.putStringArrayList(KEY_IMAGE_LIST, mSelectedImages); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup parent 
     ,Bundle savedInstanceState){ 

    View v = inflater.inflate(R.layout.fragment_photos, parent,false); 

    mSelectedImagesListView = (ListView)v.findViewById(android.R.id.list); 
    mImagesDescriptionRelativeLayout = (RelativeLayout) 
      v.findViewById(R.id.photos_descriptionRelativeLayout); 
    mImagesDescriptionEditText = (EditText)v.findViewById(R.id.photos_descriptionEditText); 
    mImagesDescriptionRelativeLayout.setVisibility(View.INVISIBLE); 

    if(savedInstanceState != null){ 

     mSelectedImages = savedInstanceState.getStringArrayList(KEY_IMAGE_LIST); 
     loadSelectedImagesListView(mSelectedImages); 
    } 



    return v; 
}//end method onCreateView 
0

雖然你可以在一個Bundle所選內容存儲與onSaveInstanceState,他們必須實現Parcelable接口。

如果您不想受到您保留的約束,請考慮使用無頭碎片。

public class RetainedFragment extends Fragment { 

    // data object we want to retain 
    private MyDataObject data; 

    // this method is only called once for this fragment 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // retain this fragment 
     setRetainInstance(true); 
    } 

    public void setData(MyDataObject data) { 
     this.data = data; 
    } 

    public MyDataObject getData() { 
     return data; 
    } 
} 

你可以找到更多here,它解釋了爲什麼使用無頭的片段最好只設置了「configChanges」屬性。

PS。作爲一般的經驗法則,對於不顯示視圖的片段,只能使用setRetainInstance(true)