4

我对 Android 比较陌生,我对列表、片段和存储一些状态数据的位置有一些疑问。我在一个示例中工作,其中我有一个使用片段的列表视图和一个详细视图。当我第一次打开应用程序时,我加载(从 Web 服务)项目列表(使用 asyntask)。我想“保存”那个列表,所以如果我需要回到这个活动(列表),我不需要再次执行异步任务。在哪里“保存”这个列表更好?Application 对象是个好地方吗?

然后,当我从列表中单击一个项目时,我想打开一个新活动并从该对象加载详细数据。将该对象传递给详细信息活动的最佳方式是什么?使用 Application 对象并从列表中获取所选项目(例如使用来自 onItemSelectedListener 的位置参数)(如果我有一个包含应用程序对象中项目的列表)?让我的“项目”对象实现 Parcelable 接口并将整个对象传递给意图?还有其他想法吗?

谢谢和对不起我的英语。

4

2 回答 2

1

如果您想永久保存数据,SQLite 是正确的选择。

如果你想临时缓存数据,savedInstanceState Bundle 就在这里。我向您展示了一个使用 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 从 Activity 发送到片段(根据 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()例如)所需的对象作为参数的(自定义)函数。这样它就不需要 Intent 并且看起来更具可读性(以及今天推荐的方式)

例子

主要思想是,当您对其执行某些操作(例如单击 ListView 的项目)时,SectionsFragment它会调用它的 parent Activity,它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);
    }
}

您的 SectionsFragment:

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 回答