2012-05-22 53 views
8

Tôi cần một giải pháp để xem triển khai máy nhắn tin. Thứ nhất, tôi đang tải dữ liệu khổng lồ từ cơ sở dữ liệu trong một trang, vì vậy đôi khi trong quá trình vuốt nó làm chậm tần suất quét (bạn cần vuốt nhiều lần trên trang) như trong nền đang thực hiện tìm nạp tác vụ. Tôi không sử dụng tác vụ không đồng bộ để trả lại chế độ xem. Có cách nào để tải các trang lười biếng chỉ cho phép người dùng truy cập trang khác bằng cách vuốt nhưng dữ liệu bị tải chậm.tải dữ liệu Android không đồng bộ trong máy nhắn tin xem

Mẫu mã của tôi như sau;

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; 
} 

Tôi đang gọi phương thức này trong khi tạo.

pager=(ViewPager) findViewById(R.id.pagerAdapter); 
pager.setAdapter(new SimplePager(MyPager.this)); 
pager.setCurrentItem(364); 

Có giải pháp nào không?

Trả lời

0

Tôi không nghĩ rằng có bất kỳ cách nào để tải dữ liệu lười theo kiểu đồng bộ mà bạn mô tả. AsyncTask là cách để đi hoặc có lẽ bạn có thể sử dụng các chủ đề trực tiếp. Tôi tin rằng AsyncTask được thiết kế đặc biệt cho loại chức năng này. Nó dễ dàng hơn để sử dụng sau đó các chủ đề trực tiếp. Nếu bạn cần ý tưởng về triển khai, hãy xem: http://geekjamboree.wordpress.com/2011/11/22/asynctask-call-web-services-in-android/

+1

Tôi không thể thấy bất kỳ triển khai trình xem trang nào trong liên kết đã cho. – Hanry

+0

Ví dụ về chế độ xem trang, bạn có thể xem: http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html và http://android-developers.blogspot.in/2011/08/horizontal -view-swiping-with-viewpager.html. Bạn cần phải kết nối kiểu triển khai này với AsyncTask để có được trải nghiệm người dùng tối ưu. –

17

Tôi khuyên bạn nên làm việc với Phân đoạn (và không trực tiếp với chế độ xem).

Bạn cần một giao diện trên những mảnh vỡ của mình để nói với họ khi chúng được hiển thị:

public interface IShowedFragment { 

    public void onShowedFragment(); 
} 

Làm cho tất cả các mảnh vỡ của bạn thực hiện giao diện đó, và trong phương pháp mà gọi bộ tải/asyncTasks/nhiệm vụ nền của bạn.

Sau đó đặt một onPageChangeListener trên ViewPager của bạn và khi bạn phát hiện người dùng đã thay đổi trang, hãy gọi phương thức giao diện trên đoạn của bạn. Bạn có một số lựa chọn với người nghe này, với một trong các phương pháp bạn có thể đợi cho viewPager dừng lại để trượt để kích hoạt cuộc gọi giao diện của bạn.

Để có thể nhận được phân đoạn phù hợp để thực hiện cuộc gọi này, hãy lấy mảnh từFragmentApadter.instantiateItem (ViewGroup, int) của bạn sẽ trả về đoạn cho vị trí đó nếu nó đã được tải.

mPager.setOnPageChangeListener(new OnPageChangeListener() { 

    @Override 
    public void onPageSelected(int position) { 

     Fragment fragment = (Fragment) mAdapter.instantiateItem(mPager, position); 
     if(fragment instanceof IShowedFragment){ 
      ((IShowedFragment) fragment).onShowedFragment(); 
     } 
    } 
    (...) 

Giống như bạn có thể chuẩn bị các mảnh với chế độ xem trống và khi bạn trượt trên một, bạn bắt đầu tải dữ liệu.

+0

Bạn có triển khai mẫu nào không? – Hanry

+3

Những mảnh vỡ sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều. Nếu bạn đã triển khai chúng trong một đoạn, thì bạn có thể tải dữ liệu (không đồng bộ) bất cứ khi nào bạn muốn, sau đó hiển thị chúng trên tệp createView() của Fragment. http://developer.android.com/reference/android/support/v13/app/FragmentStatePagerAdapter.html – DeeV

+1

Đã thêm một số triển khai (những gì chỉ bị thiếu là một ví dụ phân đoạn, trong đó onShowedFragment() sẽ được triển khai và tải dữ liệu của bạn một cách không đồng bộ) . – galex

1

instantiateItem được gọi khi ViewPager sắp hoán đổi và cần xem. Nó không để thực sự tạo mọi thứ. Tôi nghĩ cuối cùng, lười biếng tải là ra ngoài. Cách tôi nhìn thấy nó, có hai điều bạn sẽ cần phải làm ở đây.

1: Cache dữ liệu trong nền khi người dùng sắp đến trang của bạn. Ví dụ của bạn tuyên bố rằng 364 trang (tốt Chúa), vì vậy tôi muốn nói sử dụng một người nghe để xử lý các thay đổi trang. Khi bạn ở trang 363, bắt đầu tải dữ liệu cho 364. Khi bạn ở 364, hãy bắt đầu tải dữ liệu ở 365 và giữ dữ liệu ở mức 363 trong trường hợp người dùng muốn trao đổi lại. Nếu dữ liệu tải tương đối nhanh hoặc người dùng mất một thời gian dài để hoán đổi, nó sẽ không có vẻ giả sử bạn đang sử dụng asyncTask hoặc luồng để tải dữ liệu.

2: Có chế độ xem mặc định sao lưu không được điền cho đến khi dữ liệu được truy lục. Bạn sẽ cần phải làm điều này với tùy chọn 1 cũng như trong trường hợp người dùng tải trang trước khi bạn lấy dữ liệu.Về cơ bản, chỉ cần có chế độ xem cho biết "đang tải ..." hoặc nội dung nào đó cho đến khi bạn có dữ liệu. Hoặc là, hoặc điền dữ liệu vào thời gian thực khi bạn nhận được nó. Trong trường hợp đó, người dùng sẽ thấy nó xây dựng.

Dù bằng cách nào, tôi nghĩ bạn sẽ cần phải lưu vào bộ nhớ cache thứ gì đó để làm cho ứng dụng trông đẹp mắt.

+0

Trong nhật ký, tôi có thể thấy rằng máy nhắn tin xem bắt đầu tải dữ liệu cho 363,364,365 đồng thời khi tôi đặt mục hiện tại là 364.do đó, không có vấn đề gì cho lần tải đầu tiên nhưng khi người dùng vuốt, nói từ 364 đến 365 viewpager bắt đầu tải dữ liệu cho trang 366 nhưng nếu dữ liệu trong trang 366 rất cao thì tôi có thể thấy chế độ xem bị đóng băng trong vài giây. – Hanry

+0

Sau đó, điều đó có nghĩa là bạn đang tải dữ liệu đồng bộ cho ba trang khác nhau trên chuỗi giao diện người dùng, hai trong số đó thậm chí không hiển thị. Ngoài ra, một nửa công việc của bạn được thực hiện. Sử dụng một sợi và nó sẽ tăng tốc độ đáng kể. – DeeV

+0

Bạn vẫn cần một chế độ xem "chưa hoàn tất" mặc định trong trường hợp bạn chưa truy xuất tất cả dữ liệu của mình khi người dùng vuốt. – DeeV

0

Bạn đã xem xét android ignition library? theo Sample-applications có một thành phần "Danh sách Endless" và một thành phần http-cache.

tôi havent thử nó bản thân mình và không biết nếu điều này là một giải pháp cho bạn-chỉ thấy các ví dụ .....

3

Tôi vừa hoàn thành một nhiệm vụ rất giống nhau. Để giúp bạn bắt đầu tìm kiếm giải pháp cho vấn đề của mình, hãy xem xét các điểm sau theo thứ tự;

  1. Xem liệu bạn có cần tìm nạp tất cả dữ liệu đó trong trường hợp đầu tiên hay không. Vui lòng đăng lại với một số chi tiết về thông tin bạn cần tải và những gì bạn đang thực hiện với nó (hiển thị nó dưới dạng danh sách trên màn hình?)
  2. Nhìn vào sử dụng CursorLoader s thực hiện các tác vụ nâng hạng nặng như vậy khi cơ sở dữ liệu tìm nạp không đồng bộ. This tutorial trên mạng nội bộ giới thiệu cách tiếp cận ContentProvider Android. Tốt nhất là tự làm quen với tài liệu URI Android và ContentProvider chính thức nếu các thuật ngữ đó không có ý nghĩa nhiều.
  3. Nếu bạn đang làm việc với Phân đoạn - Hãy xem sử dụng FragmentStatePagerAdapter thay vì số FragmentPagerAdapter truyền thống. Tôi đã không sử dụng bộ điều hợp này nhưng tôi đã đọc rằng nó chỉ instantiates Fragment hiện có thể nhìn thấy, tức là không những mảnh vỡ bên phải hoặc bên trái của tab hiện đang được chọn.
  4. Xem xét tối ưu hóa truy vấn bạn đang chạy với DB.
+0

Đồng ý với DeeV. Nhiệm vụ này sẽ trở nên dễ dàng hơn (và tiêu chuẩn hơn) nếu Fragment được sử dụng cho mỗi ViewPager, trang. Khi Fragment được hiển thị, onCreateView sẽ được gọi là nơi bạn có thể khởi tạo '' '' CursorLoader''''s etc cho truy cập async db và UI không có vẻ. Điều này chắc chắn có thể trái với những nhận xét trên kể từ khi nhiều người, nhiều người khác đã làm điều đó. – OceanLife

1

Tôi gặp sự cố tương tự. Một người xem đang tải dữ liệu nặng. Nếu bạn không thường xuyên thay đổi quan điểm của các trang riêng lẻ, thì tôi khuyên bạn nên giữ các trang trong bộ nhớ. Sử dụng đoạn mã sau để thực hiện điều này

mViewPager.setOffscreenPageLimit(#pages); to keep #pages in memory. I had 5 pages so my #pages was 4. 

Nếu bạn muốn làm mới dữ liệu trên slide ViewPager, sử dụng

mViewPager.getAdapter().notifyDataSetChanged(); with getItemPosition() returning POSITION_NONE. 

Và sử dụng FragmentStatePagerAdapter.

Các vấn đề liên quan