2015-06-26 52 views
7
I have a `cursorLoader` which is working fine. 

問題是我沒有像我應該這樣使用它,我將數據從cursorLoader加載到arrayLists然後使用列表。如何在ViewPager中使用cursorLoader?

我發現本教程展示瞭如何使用cursorLoaderviewPager,但我不明白如何真正實現它。

http://tumble.mlcastle.net/post/25875136857/bridging-cursorloaders-and-viewpagers-on-android

我有一個看起來像這樣一個片段:

public class FirstFragment extends Fragment { 
    MapView mapView; 
    GoogleMap map; 
    // Store instance variables 
    private String email,about,imagepath,latitude,longitude; 
    Button getDirections; 

    // newInstance constructor for creating fragment with arguments 
    public static FirstFragment newInstance(String email,String about,String imagepath, String latitude, String longitude) { 
     FirstFragment fragmentFirst = new FirstFragment(); 
     Bundle args = new Bundle(); 
     args.putString("email", email); 
     args.putString("about", about); 
     args.putString("imagepath", imagepath); 
     args.putString("latitude", latitude); 
     args.putString("longitude", longitude); 
     fragmentFirst.setArguments(args); 
     return fragmentFirst; 
    } 

    // Store instance variables based on arguments passed 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     email = getArguments().getString("email"); 
     about = getArguments().getString("about"); 
     imagepath = getArguments().getString("imagepath"); 
     latitude = getArguments().getString("latitude"); 
     longitude = getArguments().getString("longitude"); 
    } 

    // Inflate the view for the fragment based on layout XML 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          final Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.zzfragment_pager_items, container, false); 
     ImageView imageView = (ImageView) view.findViewById(R.id.listpager_imageView); 
     TextView about = (TextView) view.findViewById(R.id.listpager_text); 
     TextView emaill = (TextView) view.findViewById(R.id.listpager_title); 
     about.setText(this.about); 
     emaill.setText(this.email); 

     ImageLoader imageLoader = ImageLoader.getInstance(); 
     DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true) 
       .cacheOnDisc(true).resetViewBeforeLoading(true) 
       .considerExifParams(true) 
       .build(); 
     imageLoader.getInstance().displayImage(imagepath, imageView, options); 

     getDirections = (Button) view.findViewById(R.id.getdirections); 

     getDirections.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       String strUri = "http://maps.google.com/maps?q=loc:" + latitude + "," + longitude + " (" + email + ")"; 
       Intent mapIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(strUri)); 

       mapIntent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"); 

       getActivity().startActivity(mapIntent); 

      } 
     }); 

//  View v = inflater.inflate(R.layout.listviewtopager, container, false); 
     // Gets the MapView from the XML layout and creates it 
     mapView = (MapView) view.findViewById(R.id.mapview); 
     mapView.onCreate(savedInstanceState); 

     // Gets to GoogleMap from the MapView and does initialization stuff 
     map = mapView.getMap(); 
     map.getUiSettings().setMyLocationButtonEnabled(false); 
     map.setMyLocationEnabled(true); 

     // Needs to call MapsInitializer before doing any CameraUpdateFactory calls 
     MapsInitializer.initialize(this.getActivity()); 

     // Updates the location and zoom of the MapView 
     CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude)), 10); 
     map.animateCamera(cameraUpdate); 

     return view; 
    } 

    @Override 
    public void onResume() { 
     mapView.onResume(); 
     super.onResume(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mapView.onDestroy(); 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     mapView.onLowMemory(); 
    } 
} 

而我稱它在這個類:

public class ViewPagerFragment extends FragmentActivity implements 
     LoaderManager.LoaderCallbacks<Cursor>{ 

    ArrayList<String> e 

mail = new ArrayList<String>(); 
ArrayList<String> about = new ArrayList<String>(); 

ArrayList<String> imagepath = new ArrayList<String>(); 

ArrayList<String> latitude = new ArrayList<String>(); 

ArrayList<String> longitude = new ArrayList<String>(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_view_pager_fragment); 
    getLoaderManager().initLoader(1, null, this); 
} 

private SmartFragmentStatePagerAdapter adapterViewPager; 

// Extend from SmartFragmentStatePagerAdapter now instead for more dynamic ViewPager items 
public static class MyPagerAdapter extends SmartFragmentStatePagerAdapter { 
    private final ArrayList<String> email; 
    private final ArrayList<String> about; 
    private final ArrayList<String> imagepath; 
    private final ArrayList<String> latitude; 
    private final ArrayList<String> longitude; 
    private int listPosition; 

    public MyPagerAdapter(FragmentManager fragmentManager,ArrayList<String> email,ArrayList<String> about, ArrayList<String> imagepath,ArrayList<String> latitude,ArrayList<String> longitude,int lPosition) { 
     super(fragmentManager); 
     this.imagepath=imagepath; 
     this.email=email; 
     this.about = about; 
     this.latitude= latitude; 
     this.longitude = longitude; 
     listPosition = lPosition; 
    } 

// Returns total number of pages 
@Override 
public int getCount() { 
    return email.size(); 
} 



// Returns the fragment to display for that page 
    @Override 
     public Fragment getItem(int position) { 
//   return FirstFragment.newInstance(listPosition+position, email.get(listPosition+position)); 
      return FirstFragment.newInstance(email.get(position), about.get(position),imagepath.get(position),latitude.get(position),longitude.get(position)); 
    } 

    // Returns the page title for the top indicator 
    @Override 
    public CharSequence getPageTitle(int position) { 
     return "Page " + position; 
    } 

} 

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    String[] projection = 
      { 
        ActivitiesTable.KEY_EMAIL, 
        ActivitiesTable.KEY_ABOUT, 
        ActivitiesTable.KEY_IMAGEPATH, 
        ActivitiesTable.KEY_LATITUDE, 
        ActivitiesTable.KEY_LONGITUTDE 

      }; 
    CursorLoader cursorLoader = new CursorLoader(this, NameContentProvider.NAME_ACTIVITIES_URI, projection, 
      null, null, null); 
    return cursorLoader; 
} 

@Override 
public void onLoadFinished(android.content.Loader<Cursor> loader, Cursor cursor) { 
    if (cursor != null && cursor.getCount() > 0) { 
     cursor.moveToFirst(); 
     do { 
      email.add(cursor.getString(cursor 
        .getColumnIndexOrThrow("email"))); 
      about.add(cursor.getString(cursor 
        .getColumnIndexOrThrow("about"))); 
      imagepath.add(cursor.getString(cursor 
        .getColumnIndexOrThrow("imagepath"))); 
      latitude.add(cursor.getString(cursor 
        .getColumnIndexOrThrow("serverLatitude"))); 
      longitude.add(cursor.getString(cursor 
        .getColumnIndexOrThrow("serverLongitude"))); 
     } while (cursor.moveToNext()); 
    } 

    int listPosition = getIntent().getExtras().getInt("position"); 


    ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager); 
    adapterViewPager = new MyPagerAdapter(getSupportFragmentManager(),email,about,imagepath,latitude,longitude,listPosition); 
    vpPager.setAdapter(adapterViewPager); 
    vpPager.setCurrentItem(listPosition); 

} 

@Override 
public void onLoaderReset(android.content.Loader<Cursor> loader) { 



    } 
} 

如何修改使用viewPager代碼使用該教程直接使用加載器,而不是將所有內容都存儲在列表中,然後使用列表?

+0

首先,不是處理5個不同的ArrayList,爲什麼不簡單地創建一個表示所有5個值的類並將這些對象放入一個ArrayList中?這種方法會讓你的代碼更加清潔,而對於我來說,結果還不錯,然後 –

+0

我不想再使用這些列表了。我已經找到了直接從cursorLoader使用數據的方法,但它使用了一些不贊成使用的方法。這看起來更好,但我不知道如何使它工作 –

+0

我正在使用的方法,直接從加載器加載數據沒有arraylist擴展'pagerAdapter'並使用'instantiateItem'和'destroyItem'這已被棄用。我喜歡我在這裏發佈的更多方法,但我無法使其工作。 –

回答

1

我不能評論,所以我正在寫一個答案..

您有一個實現LoaderCallbacks<Cursor>的活動。加載數據時,您的活動會收到onLoadFinished回撥。在此方法中,您的Cursor應該顯示在您的ViewPager中。

要顯示來自Cursor的數據,請在適配器上調用swapCursor方法。所以,每次加載數據時都不要創建適配器。創建一次,然後在其上調用swapCursor

此外,每次都沒有找到ViewPager - findViewById是一項繁重的操作,應該在創建視圖層次後執行。

所以,你onLoadFinished看起來就像這樣:

@Override 
public void onLoadFinished(android.content.Loader<Cursor> loader, Cursor cursor) { 
    if (adapterViewPager == null) { 
     adapterViewPager = new MyPagerAdapter(getSupportFragmentManager(), cursor); 
     vpPager.setAdapter(adapterViewPager); 
    } else { 
     adapterViewPager.swapCursor(cursor); 
    } 
} 
0

而是保持5個陣列數據的只是保持在視圖尋呼機適配器光標並在需要時從遊標加載數據。這樣,如果光標中有很多項目,UI將不會阻止。

您也可以用於交換光標添加的方法和通知數據已經改變和viewpager將被刷新,而不是每一次(完全按照你提到的鏈接)

的MyPagerAdapter重建以及將所述適配器應該是這樣的:

Cursor cursor; 

// Returns total number of pages 
@Override 
public int getCount() { 
    return cursor==null?0:cursor.getCount(); 
} 

// Returns the fragment to display for that page 
@Override 
public Fragment getItem(int position) { 
    // position the cursor first 
    cursor.moveToPosition(position); 

    // read each field 
    String email = cursor.getString(cursor 
        .getColumnIndexOrThrow("email")); 
    ... 
    return FirstFragment.newInstance(email, ...); 
} 

public void swapCursor(Cursor cursor) { 
    this.cursor = cursor; 
    // notify that data has changed and viewpager needs to be refreshed 
    notifyDataSetChanged(); 
} 

不要忘記清潔一次加載器復位

@Override 
public void onLoaderReset(android.content.Loader<Cursor> loader) { 
    adapterViewPager.swapCursor(null) 
} 
1

首先我會做,如果我在你身邊是創建一個模型類,它將保存你的光標中包含的信息。

public class Information implements Parcelable { 

    public String imagepath; 
    public String email; 
    public String about; 
    public String latitude; 
    public String longitude; 


protected Information(Parcel in) { 
    imagepath = in.readString(); 
    email = in.readString(); 
    about = in.readString(); 
    latitude = in.readString(); 
    longitude = in.readString(); 
} 

@Override 
public int describeContents() { 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeString(imagepath); 
    dest.writeString(email); 
    dest.writeString(about); 
    dest.writeString(latitude); 
    dest.writeString(longitude); 
} 

@SuppressWarnings("unused") 
public static final Parcelable.Creator<Information> CREATOR = new Parcelable.Creator<Information>() { 
    @Override 
    public Information createFromParcel(Parcel in) { 
     return new Information(in); 
    } 

    @Override 
    public Information[] newArray(int size) { 
     return new Information[size]; 
    } 
}; 
} 

而這已經是最重要的了。我要做的第二件事是創建兩個輔助方法,一個創建這個類的一個實例,從Cursor讀取數據,另一個創建一個集合。

public static Information createInfoFromCursor(Cursor c) { 
     Information info = new Information(); 
     info.email = cursor.getString(cursor 
        .getColumnIndexOrThrow("email"))); 
     info.about = cursor.getString(cursor 
        .getColumnIndexOrThrow("about"))); 
     info.imagepath =(cursor.getString(cursor 
        .getColumnIndexOrThrow("imagepath"))); 
     info.latitude = (cursor.getString(cursor 
        .getColumnIndexOrThrow("serverLatitude"))); 
     info.longitude = (cursor.getString(cursor 
        .getColumnIndexOrThrow("serverLongitude"))); 
     return info; 
    } 

public static ArrayList<Information> createInfoListFromCursor(Cursor c) { 
    ArrayList<Information> info = new ArrayList<>(); 
    while(c.moveToNext()) { 
     info.add(createInfoFromCursor()); 
    } 
    return info; 
} 

現在你可以決定提供Cursor,或ArrayList<Information>,到適配器。如果您決定通過Cursor,在適配器中,你將有

Cursor cursor; 

public MyPagerAdapter(FragmentManager fragmentManager,Cursor c) { 
    super(fragmentManager); 
    cursor = c; 
} 


@Override 
public Fragment getItem(int position) { 
    cursor.moveAtPosition(position); 
    Information info = createInfoFromCursor(cursor); 
    // create a version of `newInstance` that takes an Information object 
    return FirstFragment.newInstance(info); 
} 

@Override 
public int getCount() { 
    return cursor == null ? 0 : cursor.getCount(); 
}  

public Cursor swapCursor(Cursor newCursor) { 
    if (newCursor == cursor) { 
     return null; 
    } 
    cursor = newCursor; 
    if (newCursor != null) { 
     notifyDataSetChanged(); 
    } 
    return oldCursor; 
} 
在活動

,創建適配器的實例,傳遞一個空指針,並把它作爲成員CLASSE。當onLoadFinished被調用時,使用該引用調用swapCursor,刷新適配器的數據集

0

如果你正在尋找如何填充ViewPager從遊標碎片好簡單例子,看看this Activity我的代碼爲FOSDEM Companion應用程序編寫。

注意:您應該避免將地圖放入ViewPager中,因爲觸摸事件將被MapView攔截,並且用戶將無法滑動到下一頁或上一頁。

相關問題