存储状态数据的更好方式/位置(listview)

时间:2012-08-14 16:29:05

标签: android

我对Android相对较新,我对列表,片段以及存储某些状态数据的位置有一些疑问。 我正在一个例子中,我有一个列表视图和一个使用片段的详细视图。 当我第一次打开应用程序时,我加载(从Web服务)项目列表(使用asyntask)。 我想“保存”该列表,所以如果我需要回到这个活动(列表),我不需要再次执行asynctask。 哪个是“保存”此列表的更好地方? Application对象是个好地方吗?

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

谢谢,对不起我的英语。

2 个答案:

答案 0 :(得分: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);
}

我也在我的一些应用程序上使用webservices,而且当我在片段之间切换视图时,savedInstanceState对于不再执行webservice调用非常有用。 当片段视图被销毁但片段仍然存在时,将应用此案例。当再次创建视图时,它将使用缓存的数据,而不是从webservices再次下载。


要将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");
}

答案 1 :(得分:0)

您应该将列表保存在任何持久存储中(并且Application不是持久存储)。 SQLite数据库最适合您的情况。

不是创建新的Activity,而是创建新的Fragment,将其添加到activity,然后使用所需的对象作为参数调用一些(自定义)函数(例如loadMyItem())。通过这种方式,它不需要在Intent中看起来更具可读性(以及今天推荐的方式)

示例

主要的想法是,当您在SectionsFragment上执行某项操作(例如,点击ListView的项目)时,它会调用它的父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
    }
}