android在视图寻呼机中异步加载数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10703083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android load data asynchronously in view pager
提问by Hanry
I need a solution for view pager implementation. Firstly I am loading huge data from database in single page,so sometimes during swipe it slows down swipe frequency(you need to multiple time swipe on page) as in background it is doing fetching task. I am not using async task for returning view. Is there any way to lazy load pages just allow user to go on other page on swipe but data is lazy loaded.
我需要一个视图寻呼机实现的解决方案。首先,我在单个页面中从数据库加载大量数据,因此有时在滑动过程中它会减慢滑动频率(您需要在页面上多次滑动),因为在后台它正在执行获取任务。我没有使用异步任务来返回视图。有什么办法可以延迟加载页面,只允许用户在滑动时进入其他页面,但数据是延迟加载的。
My code sample is as below;
我的代码示例如下;
public Object instantiateItem(View container, int position) {
View v;
v = View.inflate(context,R.layout.swipearea, null);
listView = (ListView)v.findViewById(R.id.MyListView);
largeDataCall();
((ViewPager)container).addView(v);
return v;
}
I am calling this in on create method.
我在 create 方法中调用它。
pager=(ViewPager) findViewById(R.id.pagerAdapter);
pager.setAdapter(new SimplePager(MyPager.this));
pager.setCurrentItem(364);
Is there any solution?
有什么解决办法吗?
回答by galex
I would suggest to work with Fragments (and not directly with views).
我建议使用 Fragments (而不是直接使用视图)。
You need an Interface on your fragments to tell them when they are shown:
您需要在片段上有一个接口来告诉它们何时显示:
public interface IShowedFragment {
public void onShowedFragment();
}
Make all your fragments implement that interface, and in that method call your loaders/asyncTasks/background tasks.
让所有片段都实现该接口,并在该方法中调用您的 loader/asyncTasks/background 任务。
Then put an onPageChangeListener on your ViewPager, and when you detect the user changed the page, call the interface method on your fragment. You have some choices with this listener, with one of the methods you can wait for the viewPager to stop to slide to trigger your interface call.
然后在您的 ViewPager 上放置一个 onPageChangeListener,当您检测到用户更改了页面时,调用您的片段上的接口方法。您可以使用此侦听器进行一些选择,其中一种方法可以等待 viewPager 停止滑动以触发您的界面调用。
To be able to get the right fragment to make this call, take the fragment from yourFragmentApadter.instantiateItem(ViewGroup, int) which will return the fragment for that position if it is already loaded.
为了能够获得正确的片段来进行此调用,请从 yourFragmentApadter.instantiateItem(ViewGroup, int) 中获取片段,如果该片段已经加载,它将返回该位置的片段。
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
Fragment fragment = (Fragment) mAdapter.instantiateItem(mPager, position);
if(fragment instanceof IShowedFragment){
((IShowedFragment) fragment).onShowedFragment();
}
}
(...)
Like that you can prepare your fragments with empty views and when you slide on one, you start to load the data.
像这样你可以用空视图准备你的片段,当你滑动一个时,你开始加载数据。
回答by OceanLife
I have just completed a very similar task. To get you started on finding the solution to your problem consider the following points in order;
我刚刚完成了一个非常相似的任务。为了让您开始寻找问题的解决方案,请按顺序考虑以下几点;
- Look at whether you need to be fetching allof that data in the first instance. Feel free to post back with some detail as to what information you are needing to be loaded and what you are doing with it (displaying it as a list on screen?)
- Look at using
CursorLoader
s which perform heavy-lifting tasks such as database fetches asynchronously. This tutorialon the interwebs introduces the ContentProvider Android approach. Best to familiarise yourself with the official Android URI and ContentProvider documentation if those terms don't mean much. - If you are working with Fragments - Look at using the
FragmentStatePagerAdapter
instead of the traditionalFragmentPagerAdapter
. I haven't used this adapter but I have read that it only instantiates the currently visible Fragment, i.e. not those Fragments to the right or left of the currently selected tab. - Look at optimising the query you are running against the DB.
- 看看您是否需要在第一个实例中获取所有这些数据。请随意回帖,详细说明您需要加载哪些信息以及您正在使用它做什么(在屏幕上显示为列表?)
- 看看 using
CursorLoader
s 执行繁重的任务,例如异步获取数据库。互联网上的本教程介绍了 ContentProvider Android 方法。如果这些术语没有多大意义,最好熟悉官方 Android URI 和 ContentProvider 文档。 - 如果您正在使用 Fragments - 看看使用
FragmentStatePagerAdapter
而不是传统的FragmentPagerAdapter
. 我没有使用过这个适配器,但我读到它只实例化当前可见的 Fragment,即不是当前选定选项卡右侧或左侧的那些 Fragment。 - 查看优化您针对数据库运行的查询。
回答by RaWa
I had a similar problem. A viewpager which was loading heavy data. If you are not going to change the views of the individual pages often, then I would suggest you keep the pages in memory. Use following code to perform this
我有一个类似的问题。正在加载大量数据的 viewpager。如果您不打算经常更改单个页面的视图,那么我建议您将页面保留在内存中。使用以下代码执行此操作
mViewPager.setOffscreenPageLimit(#pages); to keep #pages in memory. I had 5 pages so my #pages was 4.
If you want to refresh data on the viewpager slides, use
如果要刷新 viewpager 幻灯片上的数据,请使用
mViewPager.getAdapter().notifyDataSetChanged(); with getItemPosition() returning POSITION_NONE.
And use FragmentStatePagerAdapter.
并使用 FragmentStatePagerAdapter。
回答by DeeV
instantiateItem
is called when the ViewPager
is about to swap and needs a view. It doesn't haveto actually create everything. I think ultimately, lazy-loading is out. The way I see it, there's two things you'll need to do here.
instantiateItem
在ViewPager
即将交换并需要视图时调用。它并不具备真正创造一切。我认为最终,延迟加载已经过时了。在我看来,你需要在这里做两件事。
1: Cache the data in the background when the user is about to reach your page. Your example claims that 364 pages (good Lord), so I'd say use a listener to handle page changes. When you're at page 363, start loading the data for 364. When you're at 364, start loading the data at 365 and keep the data at 363 in case the user wants to swap back. If the data loads relatively quickly or the user takes a long time to swap, it should be seemless assuming you're using asyncTask or thread to load the data.
1:在用户即将到达您的页面时在后台缓存数据。您的示例声称 364 页(上帝),所以我会说使用侦听器来处理页面更改。当您在第 363 页时,开始加载 364 的数据。当您在 364 时,从 365 开始加载数据并将数据保持在 363,以防用户想要换回。如果数据加载相对较快或者用户需要很长时间进行交换,那么假设您使用 asyncTask 或线程加载数据应该是没有问题的。
2: Have a backup default view that doesn't get populated until the data is retrieved. You'll need to do this with option 1 as well in case the user loads the page before you retrieve the data. Basically, just have a view that says "loading..." or something until you have the data. Either that, or populate the data at real time as you get it. In that case the user will see it build.
2:拥有一个备份默认视图,在检索数据之前不会填充该视图。您还需要使用选项 1 执行此操作,以防用户在检索数据之前加载页面。基本上,只要有一个显示“正在加载...”或其他内容的视图,直到您拥有数据。要么,要么在获得数据时实时填充数据。在这种情况下,用户将看到它的构建。
Either way, I think you'll need to cache something to make the app look good.
无论哪种方式,我认为您都需要缓存一些东西才能使应用程序看起来不错。
回答by k3b
Have you looked into android ignition library? according to Sample-applicationsthere is a a component "Endless List" and a http-cache component.
您是否查看过android 点火库?根据示例应用程序,有一个组件“Endless List”和一个 http-cache 组件。
I havent tried it myself and dont know if this is a solution for you-just saw the examples.....
我自己还没有尝试过,不知道这是否适合您-刚刚看到示例.....
回答by Code Poet
I do not think there's any way to lazy load data in the synchronous fashion that you describe. AsyncTask is the way to go or perhaps you could use threads directly. I believe AsyncTask was designed specifically for this kind of functionality. It's easier to use then the thread directly. If you need ideas on implementation, have a look at: http://geekjamboree.wordpress.com/2011/11/22/asynctask-call-web-services-in-android/
我认为没有任何方法可以以您描述的同步方式延迟加载数据。AsyncTask 是可行的方法,或者您可以直接使用线程。我相信 AsyncTask 是专门为这种功能设计的。直接使用线程更容易。如果您需要有关实施的想法,请查看:http: //geekjamboree.wordpress.com/2011/11/22/asynctask-call-web-services-in-android/