캡션이있는 이미지를 표시하는 데 액티비티 중 하나를 사용하는 앱을 만들고 있습니다. 이러한 이미지는 ViewPager (한 페이지의 각 이미지)를 사용하여 표시됩니다.Android 기기를 돌릴 때 이미지를 유지하는 중
이미지를 만들고 캡션과 함께 표시하는 데 아무런 문제가 없습니다. 그러나 장치를 회전 할 때 문제가 발생합니다. 장치가 회전하면 이미지는 삭제되지만 캡션은 그대로 유지됩니다. 나는 그 이유를 알고 있다고 생각한다. (아래의 코드 단락에 설명되어있다.) 그러나 나는 그것을 풀 수 없다. 그러므로 나는이 질문을하고있다. 그런 다음 활동 코드 GalleryItemPagerActivity.java
아래
public class GalleryItemPagerActivity extends Activity {
private ViewPager mViewPager;
private NewsItem mNewsItem;
private int mNewsItemId;
ImageDownloaderThread<ImageView> mImageDownloaderThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.galleryItemViewPager);
setContentView(mViewPager);
// Create a thread that will be run in the background to download images from the web for each URL
//
// IMPORTANT NOTE:
// We are downloading the image in the activity instead of the fragment because we are use a pager activity
// ... and pager activities must have the adapter in the activity rather than the fragment, which causes us to download the image here
// ... if we try to download in the fragment, then we will have a very complicated code that will cause too many memory leaks.
mImageDownloaderThread = new ImageDownloaderThread<ImageView>(new Handler());
// Prepare listener to update UI when an image is downloaded
mImageDownloaderThread.setListener(new ImageDownloaderThread.Listener() {
// This method is used to update the UI when the image ready
public void onImageDownloaded(Bitmap image, String url, int pos, int download_image_type) {
// First, get the fragment by position
GalleryItemFragment fragment = ((GalleryItemFragmentStatePagerAdapter)mViewPager.getAdapter()).getFragment(pos);
// If the fragment exists
if (fragment != null) {
// Update the image
ImageView imageView = (ImageView) fragment.getView().findViewById(R.id.gallery_image);
imageView.setImageBitmap(image);
}
}
});
// Start the background thread
mImageDownloaderThread.start();
// Prepare the looper for the background thread
mImageDownloaderThread.getLooper();
mNewsItemId = getIntent().getIntExtra(GalleryItemFragment.EXTRA_NEWS_ITEM_ID, 0);
mNewsItem = NewsItems.get(this).getNewsItem(mNewsItemId);
FragmentManager fm = getFragmentManager();
GalleryItemFragmentStatePagerAdapter adapter = new GalleryItemFragmentStatePagerAdapter(fm);
mViewPager.setAdapter(adapter);
}
// Destroy the background thread when we exit the app, otherwise it will stay forever
@Override
public void onDestroy() {
super.onDestroy();
mImageDownloaderThread.quit();
}
// I am subclassing FragmentStatePagerAdapter so I can add the method getFragment()
// ... This method allows me to get the displayed fragment by position, and if it does not exist, a null is returned.
private class GalleryItemFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// A map to track current fragments.
private Map<Integer, GalleryItemFragment> mFragmentReferenceMap = new HashMap<Integer, GalleryItemFragment>();
// Constructor
public GalleryItemFragmentStatePagerAdapter(FragmentManager fm) {
super(fm);
}
// Implementation of get count.
@Override
public int getCount() {
// The number of images to download is the number of our fragments
int count = mNewsItem.getImages().size();
return count;
}
// Fragment to display, and download the main image and author avatar
@Override
public Fragment getItem(int pos) {
// Download this image
String imageUrl = mNewsItem.getImages().get(pos).getUrl();
// Initiate a request to download the image at the background thread
mImageDownloaderThread.queueImage(imageUrl, pos, ImageDownloaderThread.DOWNLOAD_IMAGE_TYPE_MAIN);
// Get the fragment
GalleryItemFragment fragment = GalleryItemFragment.newInstance(mNewsItemId, pos);
// Add the fragment to our map
mFragmentReferenceMap.put(Integer.valueOf(pos), fragment);
return fragment;
}
// When a fragment is deleted, we have to remove it from the map
@Override
public void destroyItem(ViewGroup container, int pos, Object object) {
mFragmentReferenceMap.remove(Integer.valueOf(pos));
// Remove the fragment from the map
mFragmentReferenceMap.remove(Integer.valueOf(pos));
}
// Get the fragment by position (returns null if fragment does not exist)
public GalleryItemFragment getFragment(int key) {
return mFragmentReferenceMap.get(Integer.valueOf(key));
}
}
}
입니다 그리고 조각의 코드가 GalleryItemFragment.java
에 적합한
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView android:id="@+id/gallery_image"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:scaleType="fitCenter"
android:background="@color/black" />
<TextView android:id="@+id/gallery_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="right"
android:textSize="20sp"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:textColor="@color/white"
android:background="@color/transparent_black_percent_50" />
</FrameLayout>
:
먼저, 여기에 각각의 이미지를 표시하는 데 사용되는 내 gallery_item.xml
파일입니다
public class GalleryItemFragment extends Fragment {
public static final String EXTRA_NEWS_ITEM_ID = "com.myproject.android.news_item_id";
public static final String EXTRA_GALLERY_ITEM_POSITION = "com.myproject.android.gallery_item_position";
private int mNewsItemId;
private int mGalleryItemPosition;
private TextView mCaptionField;
// This is used to set attach arguments to the fragment
public static GalleryItemFragment newInstance (int news_item_id, int gallery_item_position) {
Bundle args = new Bundle();
args.putInt(EXTRA_NEWS_ITEM_ID, news_item_id);
args.putInt(EXTRA_GALLERY_ITEM_POSITION, gallery_item_position);
GalleryItemFragment fragment = new GalleryItemFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNewsItemId = getArguments().getInt(EXTRA_NEWS_ITEM_ID);
mGalleryItemPosition = getArguments().getInt(EXTRA_GALLERY_ITEM_POSITION);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
// inflate our xml file first
View v = inflater.inflate(R.layout.gallery_item, parent, false);
mCaptionField = (TextView)v.findViewById(R.id.gallery_caption);
mCaptionField.setText(NewsItems.get(getActivity()).getNewsItem(mNewsItemId).getImages().get(mGalleryItemPosition).getCaption());
return v;
}
}
이제 엠.
앞에서 설명한 것처럼 장치를 회전하면 활동이 삭제되지만 조각은 그대로 유지됩니다 (수락 된 답변 here에서 설명).
또한 내 사례의 이미지가 프래그먼트가 아닌 활동에 다운로드된다는 것을 알았습니다 (페이징 활동을 사용하기 때문에 어댑터가 프래그먼트가 아닌 활동에 있어야 함).
그래서 활동이 파괴되면 이미지는 사라집니다 (그러나 캡션은 보존 된 조각의 일부이므로 유지됩니다). 따라서 이미지가없는 검은 색 페이지가되지만 캡션 만 표시됩니다.
는 지금, 나는 다른 솔루션 (예 : this one)를 읽고, 나는 AndroidManifest.xml
android:configChanges="orientation|screenSize"
에 다음 줄을 추가하려고하지만 왼쪽으로 슬라이딩 할 때 이미지가 '불균형'보면이 훨씬 도움이되지 않았다 화면 크기를 유지하는 screenSize
속성 때문에 장치를 회전 한 직후에 우스운 이미지가 나타납니다.
지금, 나는 onSaveInstanceState()
을 시도해야한다고 생각하지만 그렇게하는 방법을 모르겠다. onSaveInstanceState()
을 사용하여 이미지를 저장하고 유지하려면 어떻게해야합니까? 내 액티비티 클래스의 다른 변수 (예 : mViewPager
)는 저장해야합니까?
감사합니다.
이미지를 처리하기 위해 LruCache와 함께'onConfigurationChanged()'를 사용하여 끝내게되었습니다. – Greeso