2

私は Android 開発を学ぼうとしていますが、フレームワークがどのように機能するか、これらすべてのクラスを適切に拡張する方法について頭を悩ませようとしています。

私の目標は次のとおりActivityです。それぞれにバインドされているデータは、 を使用して呼び出される Web API から取得されます。 ViewPagerListFragmentListFragmentAsyncTask

私の問題は、新しいフラグメントに切り替えるたびにMyListFragment.newInstance()が再度呼び出され、AsyncTask毎回 が呼び出されることです。Web呼び出しを減らしてページの状態を保存するためにAsyncTask、最初にロードされたときに一度呼び出されるようにしようとしています。ListFragment最終的には、「プルダウンして更新」タイプのことをしたいと思います。これは、ページを切り替えたときにデータをリロードしないことを意味します。

これを実現するために、Android Developersのこのガイドに従っています。私が最終的に得たのはこれです:

public class MainActivity extends FragmentActivity {

    MyPagerAdapter mMyPagerAdapter;
    ViewPager mViewPager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMyPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mMyPagerAdapter);
    }


    public class MyPagerAdapter extends FragmentPagerAdapter {
        public static final int NUM_PAGES = 5;

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

        @Override
        public Fragment getItem(int i) {
            return MyListFragment.newInstance(getPageTitle(i).toString());
        }

        @Override
        public int getCount() {
            return NUM_PAGES;
        }

        @Override
        public CharSequence getPageTitle(int position) { 
            String[] titles = getResources().getStringArray(R.array.thing_sort_titles);
            return titles[position];
        }

    }


    public static class MyListFragment extends ListFragment {
        public static final String ARG_CATEGORY = "category_title";
        ArrayList<HashMap<String, String>> mylist;

        public MyListFragment() {
            mylist = new ArrayList<HashMap<String, String>>();
        }

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

            Bundle args = getArguments();
            URI url = new URI("http://api.remotesite.com/" + args.getString(ARG_CATEGORY));
            new MyListAsyncTask().execute(url);
        }

        static MyListFragment newInstance(String category) {
            MyListFragment f = new MyListFragment();

            Bundle args = new Bundle();
            args.putString(ARG_CATEGORY, category);
            f.setArguments(args);

            return f;
        }

        private class MyListAsyncTask extends AsyncTask<URI, Integer, ArrayList<HashMap<String, String>>> {

            protected ArrayList<HashMap<String, String>> doInBackground(URI... uris) {
                try {
                    JSONArray json = JSON.getJSONfromURL(uris[0]);
                    for (int i = 0; i < json.length(); i++) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        JSONObject obj = json.getJSONObject(i)
                        map.put("title", obj.getString("title"));
                        map.put("author", obj.getString("author"));
                        map.put("id", obj.getString("id"));
                        mylist.add(map);
                    }
                } catch (Exception ex) {
                }
                return mylist;
            }

            protected void onPostExecute(ArrayList<HashMap<String, String>> list) {
                ListAdapter adapter = new SimpleAdapter(
                    getActivity(), 
                    mylist,
                    R.layout.list_item, 
                    new String[] { "title", "author" }, 
                    new int[] { R.id.text_title, R.id.text_author }
                );
                MyListFragment.this.setListAdapter(adapter);
            }
        }
    }
}

ListFragmentでs の配列を実行しようとしましたがFragmentPagerAdapter、そのインデックスが null の場合にのみ呼び出しましMyListFragment.newInstanceたが、何も変更されませんでした。

4

2 に答える 2

1

あなたのケースではローダー( http://developer.android.com/guide/components/loaders.html )を使用することをお勧めします。

ローダーは、同じ ID を使用すると、以前と同じデータを呼び出し元のコンポーネントに自動的に返すという点で非常に賢いです。

例えば:

フラグメント位置 0 呼び出しinitLoader(0, null, this);、フラグメント位置 1 呼び出しinitLoader(1, null, this);など....

そうすれば、<< id が 2 回目 (3 回目、4 回目) に呼び出されるたびinitLoader(1に、Web 呼び出しは実行されず、1 回目の呼び出しで配信されたのと同じ結果が直接配信されます。

于 2013-04-09T13:35:04.607 に答える