2

基本的に、AsyncTask を使用して URL からビットマップをダウンロードし、ImageView 内に表示する単純な Fragment があります。

これはフラグメントのコードです:

public class TestFragment extends Fragment {

public TestFragment () {}

private String pictureUrl = "https://fbcdn-sphotos-d-a.akamaihd.net/hphotos-ak-prn1/532762_10150739418088211_1186720820_n.jpg";

private TextView sampleText;
private ImageView sampleImage;

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {

    View root = inflater.inflate(R.layout.fragment_view, container, false); 
    String textToSet = "Section Three";

    sampleText = (TextView) root.findViewById(R.id.textView1);
    sampleText.setText(textToSet);

    sampleImage = (ImageView) root.findViewById(R.id.imageView1);
    DownloadImageTask task = new DownloadImageTask(pictureUrl, root, sampleImage.getId());
    task.execute();

    return root;   
}       
}

この同じフラグメントは、ActionBar 内の各タブごとに 1 つずつ、3 回表示されます。私が抱えている問題は、ユーザーが別のタブを選択するたびに前のタブが破棄され、ユーザーが元のタブに戻るときにコンテンツを再ダウンロードする必要があることです。リソースの消費量を最小限に抑えたい (データと貴重なオーバーヘッド処理の両方を節約する)。

Fragment Container アクティビティは次のとおりです。

public class LayoutContainer extends Activity{

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_layout_container);      

    if (savedInstanceState != null) {
        return;
    }

    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    Tab tab = actionBar.newTab()
            .setText(R.string.title_section1)
            .setTabListener(new TabListener<TestFragment>(
                    this, "one", TestFragment.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
            .setText(R.string.title_section2)
            .setTabListener(new TabListener<TestFragment>(
                    this, "two", TestFragment.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
            .setText(R.string.title_section3)
            .setTabListener(new TabListener<TestFragment>(
                    this, "three", TestFragment.class));
    actionBar.addTab(tab);

}

public static class TabListener<T extends Fragment> implements ActionBar.TabListener {

    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if (mFragment == null) {
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
        }
        ft.replace(android.R.id.content, mFragment, mTag);
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.addToBackStack(null);
        ft.commit();
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
}

現在、OnTabSelected()メソッドでft.replace()を呼び出すように設定していますが、以前はft.add()で試していました。OnTabUnselected () 内の現在のft.addToBackStack()呼び出しにも同じことが言えます。最初は単にft.detach()を呼び出すように設定していましたが、それは私の問題であると説明したのと同じことをしていました。そのようにロードしますが、毎回イメージをダウンロードする必要があります。

ここで、addToBackStack()を呼び出してみましたが、FragmentTransaction をバック スタックに追加できないというメッセージが表示され、アプリが強制終了します。また、データの消費を避けるために、過去に画像をオフラインでキャッシュしようとしましたが、アプリはローカル URI から画像を解析し、処理能力を使用する必要があります。

私が試すことができるアイデアはありますか?

参考までに、はい、同じフラグメントが 3 つのタブすべてに同じ画像をロードしていることはわかっています。これは、フラグメントのライフサイクルをよりよく理解するための単なるテスト プロジェクトです。

4

2 に答える 2

2

したがって、多くのことを読んだ後、重要なコードブロックはTabListenerで実行されるのではなく、実際には使用する各フラグメントで実行されることに気付きました。

フラグメントは、そこから移動するときに切り離されますが、onSaveInstanceState(...)を使用してフラグメントの状態を保持できないことを意味するわけではありません。

これは、フラグメントが切り離された後、フラグメントの状態を保持するために必要なものの簡単な実装です。

public class TimelineFragment extends ListFragment{
...

public TimelineFragment () {}

public void onSaveInstanceState(Bundle outState){
    getActivity().getFragmentManager().putFragment(outState, TAG, this);        
}

public void onRetoreInstanceState(Bundle inState){
    getActivity().getFragmentManager().getFragment(inState, TAG);
}
...
}

putFragment()を呼び出してフラグメントを保存し、getFragment()を呼び出してフラグメントを復元しています。かなり単純で、私はそれを考えたことはありませんでした。

于 2012-11-05T04:10:40.303 に答える
1

ユーザーが Web から画像を必要とする場合に私が行うこと まず、画像がキャッシュされているかどうか、または画像が SD にあるかどうかを確認します。SD またはキャッシュで画像が見つからない場合は、画像をダウンロードし、SD に保存してキャッシュに追加します。

通常は次のようになります。

    Bitmap cacheBitmap = Database.getImageFromMemory(exercise.image, getActivity());

    if(cacheBitmap != null) {
        image.setImageBitmap(cacheBitmap);
        progressBar.setVisibility(View.GONE);
    }
    Bitmap localBitmap = ImageDownloader.decodeSampledBitmap(exercise.image, width, height, getActivity());

    if(localBitmap != null) {
        image.setImageBitmap(localBitmap);
        progressBar.setVisibility(View.GONE);
        Database.addBitmapToMemoryCache(exercise.image, localBitmap, getActivity());
    } else {
        ImageDownloader imageDownloader = new ImageDownloader(this.getActivity().getApplicationContext(), image, progressBar, width, height);
        imageDownloader.execute(exercise.image);
    }

これはすべてのコードではありませんが、それを処理する方法についてのアイデアを提供します。さらにコードが必要な場合は、お気軽にお問い合わせください。ただし、正しい方向に進んでいるようです。

于 2012-10-04T08:56:12.967 に答える