4

私はAndroidに比較的慣れていないので、リスト、フラグメント、および状態データを保存する場所に関していくつか疑問があります。フラグメントを使用したリスト ビューと詳細ビューの例で作業しています。アプリを最初に開いたときに、(Web サービスから) アイテムのリストを (ayntask を使用して) ロードします。そのリストを「保存」したいので、このアクティビティ (リスト) に戻る必要がある場合は、asynctask を再度実行する必要はありません。このリストを「保存」するのに適した場所はどこですか? Application オブジェクトは良い場所ですか?

次に、リストからアイテムをクリックすると、新しいアクティビティを開き、そのオブジェクトから詳細データをロードします。そのオブジェクトを詳細アクティビティに渡す最良の方法は何ですか? Application オブジェクトを使用して、選択した項目をリストから取得します (たとえば、onItemSelectedListener の位置パラメーターを使用) (アプリケーション オブジェクトに項目を含むリストがある場合)? 「アイテム」オブジェクトに Parcelable インターフェースを実装させ、オブジェクト全体をインテント内に渡しますか? 他のアイデアはありますか?

私の英語に感謝し、申し訳ありません。

4

2 に答える 2

1

データを永久に保持したい場合は、SQLite が適切なオプションです。

データを一時的にキャッシュしたい場合は、savedInstanceState バンドルがそのためにあります。Fragment と ListView の使用例を示します。

public static final String BUNDLE_CACHE = "ListFragment.BUNDLE_CACHE";

private ArrayList<ListItem> mCachedData;
private ListView mListView;
private ListItemAdapter mListAdapter;

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

    if ((savedInstanceState != null) && savedInstanceState.containsKey(BUNDLE_CACHE)) {
        this.mCachedData = savedInstanceState.getParcelableArrayList(BUNDLE_CACHE);
    }

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);

    LinearLayout layout = (LinearLayout) inflater.inflate(
            R.layout.layout_fragment, null);

    this.mListAdapter = new ListAdapter(inflater.getContext(), 
            R.layout.item_list_topic_categories);

    this.mListView = (ListView) layout.findViewById(R.id.listView);
    this.mListView.setAdapter(this.mListAdapter);
    this.mListView.setOnItemClickListener(this.mItemClickListener);

    if (this.mCachedData == null) {
        Log.d("onCreateView", "I make the request");
        this.downloadData();
        ... // After download is finished, you put somewhere:
        this.mCachedData = downloadedData;
    } else {
        Log.d("onCreateView", "Cool, the data is cached");
        this.buildList(this.mCachedData);
    }

    return layout;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    // You put the content of your list, which is this.mCachedData, in the state
    outState.getParcelableArrayList(BUNDLE_CACHE, this.mCachedData);
}

また、一部のアプリで Web サービスを使用しています。savedInstanceState は、フラグメント間でビューを切り替えたときに Web サービスの呼び出しを繰り返さないようにするのに非常に役立ちます。このケースは、フラグメント ビューが破棄されてもフラグメントがまだ存在する場合に適用されます。ビューが再度作成されると、Web サービスから再度ダウンロードする代わりに、キャッシュされたデータが使用されます。


アクティビティからフラグメントに Parcelable を送信するには (biovamp の例に従って)、次を使用します。

Bundle args = new Bundle();
args.putParcelable("keyName", parcelableObject);
fragment.setArguments(args);

フラグメント内で、これを使用して Parcelable を取得します。

this.getArguments().getParcelable("keyName");

Parcelable を作成するには、たとえば次のチュートリアルを参照してください: http://techdroid.kbeanie.com/2010/06/parcelable-how-to-do-that-in-android.html

今、あなたは言いました:

次に、リストからアイテムをクリックすると、新しいアクティビティを開きたい

したがって、ListFragment から DetailsActivity を作成したい場合は、Intent を使用してデータを送信します。

ListItem item = ... // get your item data
intent.putExtra("keyItem", item);

そして、次を使用して、新しく作成した DetailsActivity 内に取得します。

Bundle extras = getIntent().getExtras();
if (extras !=null) {
    ListItem value = (ListItem) extras.getParcelable("keyItem");
}
于 2012-08-14T16:35:14.637 に答える
0

リストを永続ストレージのいずれかに保存する必要があります (アプリケーションは永続ストレージではありません)。あなたの場合、SQLiteデータベースが最も適しています。

新しいアクティビティを作成する代わりに、新しいフラグメントを作成し、それをアクティビティに追加してからloadMyItem()、必要なオブジェクトをパラメーターとしていくつかの (カスタム) 関数 (たとえば) を呼び出すことをお勧めします。そのような方法では、インテントは必要なく、より読みやすくなります(そして、今日の推奨方法)

主なアイデアは、何らかのアクション (たとえば、ListView のアイテムをクリックする) を実行SectionsFragmentすると、それが parentActivityを呼び出し、Activity何をどこにロードするかを決定することです。この例では、内部のデータをロードするためにActivity呼び出します。DetailFragment

あなたの活動クラス:

public class MainActivity extends Activity{

    private DetailFragment mDetailFragment;
    private SectionsFragment mSectionsFragment;

    /*initialization stuff, it's not interesting now*/

    //Section is just custom class for example - it can be whatever you want
    public void setSection(Section section){
        mDetailFragment.loadSection(section);
    }
}

あなたのセクションフラグメント:

public class SectionsFragment extends Fragment{

    /*initialization is also skipped*/

    /**This method may be called when ListView's item is touched or somwhere else - it's doesn't matter*/
    private void setSection(Section section){
        if(!(getActivity() instanceof MainActivity))
            throw new ClassCastException("This fragment can be created only by MainActivity");
        MainActivity activity = (MainActivity) getActivity();
        activity.setSection(section);
    }
}

そしてあなたのDetailFragment:

public class DetailFragment extends Fragment{

    /*initialization*/

    public void loadSection(Section section){
        //Here your fragment decides what exactly it should load
        //for this section. Maybe do some networking, or load data from database
        //whatever you want
    }
}
于 2012-08-14T16:39:19.867 に答える