ViewPager
間のスワイプにFragments
を使用していますが、ViewPager
間の単純なXMLレイアウト間のスワイプにViews
を使用できますか?
これは、フラグメント間のスワイプに使用されるViewPagerのAdapter
ページです。
import Java.util.List;
import com.app.name.fragments.TipsFragment;
import Android.support.v4.app.Fragment;
import Android.support.v4.app.FragmentManager;
import Android.support.v4.app.FragmentPagerAdapter;
import Android.support.v4.app.FragmentTransaction;
import Android.view.ViewGroup;
public class PageAdapter extends FragmentPagerAdapter {
/**
*
*/
List<Fragment> fragments;
public PageAdapter(FragmentManager fm,List<Fragment> frags) {
super(fm);
fragments = frags;
}
@Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
return TipsFragment.newInstance(0, 0);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return 4;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
FragmentManager manager = ((Fragment) object).getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove((Fragment) object);
trans.commit();
super.destroyItem(container, position, object);
}
}
そして、これは私の先端の断片です:
public class TipsFragment extends Fragment
{
public static TipsFragment newInstance(int image,int content)
{
TipsFragment fragment = new TipsFragment();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tip_layout, null);
return view;
}
}
フラグメントではなくビューで動作するようにコードを変更するにはどうすればよいですか?
getItem()
ではなく、これら2つのメソッドをオーバーライドする必要があります。
@Override
public Object instantiateItem(ViewGroup collection, int position) {
View v = layoutInflater.inflate(...);
...
collection.addView(v,0);
return v;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
この例を使用してください
子ビューをネストする単一のXMLレイアウトを使用できます。
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.v4.view.ViewPager
Android:id="@+id/pager"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<LinearLayout
Android:id="@+id/page_one"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<TextView
Android:text="PAGE ONE IN"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:textColor="#fff"
Android:textSize="24dp"/>
</LinearLayout>
<LinearLayout
Android:id="@+id/page_two"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<TextView
Android:text="PAGE TWO IN"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:textColor="#fff"
Android:textSize="24dp"/>
</LinearLayout>
</Android.support.v4.view.ViewPager>
</LinearLayout>
しかし...あなたもアダプタでこれを処理する必要があります。ここで、他のレイアウトを膨らませることなく、見つかったビューIDを返します。
class WizardPagerAdapter extends PagerAdapter {
public Object instantiateItem(ViewGroup collection, int position) {
int resId = 0;
switch (position) {
case 0:
resId = R.id.page_one;
break;
case 1:
resId = R.id.page_two;
break;
}
return findViewById(resId);
}
@Override
public int getCount() {
return 2;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override public void destroyItem(ViewGroup container, int position, Object object) {
// No super
}
}
// ViewPagerアダプタを設定します
WizardPagerAdapter adapter = new WizardPagerAdapter();
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
以前の回答に基づいて、適切かつ明確な方法でそれを達成するために次のクラスを作成しました(願っています)。
public class MyViewPagerAdapter extends PagerAdapter {
ArrayList<ViewGroup> views;
LayoutInflater inflater;
public MyViewPagerAdapter(ActionBarActivity ctx){
inflater = LayoutInflater.from(ctx);
//instantiate your views list
views = new ArrayList<ViewGroup>(5);
}
/**
* To be called by onStop
* Clean the memory
*/
public void release(){
views.clear();
views = null;
}
/**
* Return the number of views available.
*/
@Override
public int getCount() {
return 5;
}
/**
* Create the page for the given position. The adapter is responsible
* for adding the view to the container given here, although it only
* must ensure this is done by the time it returns from
* {@link #finishUpdate(ViewGroup)}.
*
* @param container The containing View in which the page will be shown.
* @param position The page position to be instantiated.
* @return Returns an Object representing the new page. This does not
* need to be a View, but can be some other container of
* the page. ,container
*/
public Object instantiateItem(ViewGroup container, int position) {
ViewGroup currentView;
Log.e("MyViewPagerAdapter", "instantiateItem for " + position);
if(views.size()>position&&views.get(position) != null){
Log.e("MyViewPagerAdapter",
"instantiateItem views.get(position) " +
views.get(position));
currentView = views.get(position);
}
else{
Log.e("MyViewPagerAdapter", "instantiateItem need to create the View");
int rootLayout = R.layout.view_screen;
currentView = (ViewGroup) inflater.inflate(rootLayout, container, false);
((TextView)currentView.findViewById(R.id.txvTitle)).setText("My Views " + position);
((TextView)currentView.findViewById(R.id.btnButton)).setText("Button");
((ImageView)currentView.findViewById(R.id.imvPicture)).setBackgroundColor(0xFF00FF00);
}
container.addView(currentView);
return currentView;
}
/**
* Remove a page for the given position. The adapter is responsible
* for removing the view from its container, although it only must ensure
* this is done by the time it returns from {@link #finishUpdate(ViewGroup)}.
*
* @param container The containing View from which the page will be removed.
* @param position The page position to be removed.
* @param object The same object that was returned by
* {@link #instantiateItem(View, int)}.
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
/**
* Determines whether a page View is associated with a specific key object
* as returned by {@link #instantiateItem(ViewGroup, int)}. This method is
* required for a PagerAdapter to function properly.
*
* @param view Page View to check for association with <code>object</code>
* @param object Object to check for association with <code>view</code>
* @return true if <code>view</code> is associated with the key object <code>object</code>
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view==((View)object);
}
}
そして、あなたはあなたのアクティビティでそれを設定しなければなりません:
public class ActivityWithViewsPaged extends ActionBarActivity {
/**
* The page Adapter: Manage the list of views (in fact here, its fragments)
* And send them to the ViewPager
*/
private MyViewPagerAdapter pagerAdapter;
/**
* The ViewPager is a ViewGroup that manage the swipe from left
* to right to left.
* Like a listView with a gesture listener...
*/
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_with_views);
// Find the viewPager
viewPager = (ViewPager) super.findViewById(R.id.viewpager);
// Instantiate the PageAdapter
pagerAdapter = new MyViewPagerAdapter(this);
// Affectation de l'adapter au ViewPager
viewPager.setAdapter(pagerAdapter);
viewPager.setClipToPadding(false);
viewPager.setPageMargin(12);
// Add animation when the page are swiped
// this instanciation only works with honeyComb and more
// if you want it all version use AnimatorProxy of the nineoldAndroid lib
//@see:http://stackoverflow.com/questions/15767729/backwards-compatible-pagetransformer
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
viewPager.setPageTransformer(true, new PageTransformer());
}
}
@Override
protected void onStop() {
super.onStop();
pagerAdapter.release();
}
XMLファイルが明らかなview_screen.xmlの場合:
<xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/screen"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:id="@+id/txvTitle"
Android:layout_width="wrap_content"
Android:layout_gravity="center"
Android:layout_height="wrap_content"
Android:layout_marginBottom="5dp"
Android:layout_marginTop="5dp"
Android:shadowColor="#FF00FF"
Android:shadowDx="10"
Android:shadowDy="10"
Android:shadowRadius="5"
Android:textSize="32dp"
Android:textStyle="italic"
Android:background="#FFFFF000"/>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="#FFFF00F0">
<TextView
Android:id="@+id/txvLeft"
Android:layout_width="wrap_content"
Android:layout_gravity="left"
Android:layout_height="wrap_content"
Android:layout_marginBottom="5dp"
Android:layout_marginTop="5dp"/>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_weight="1"/>
<TextView
Android:id="@+id/txvRight"
Android:layout_width="wrap_content"
Android:layout_gravity="right"
Android:layout_height="wrap_content"
Android:layout_marginBottom="5dp"
Android:layout_marginTop="5dp"/>
</LinearLayout>
<Button
Android:id="@+id/btnButton"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"/>
<ImageView
Android:id="@+id/imvPicture"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="center"/>
</LinearLayout>
また、ActivtyMainのレイアウトは次のとおりです。
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.view.ViewPager
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:paddingLeft="24dp"
Android:paddingRight="24dp"
Android:id="@+id/viewpager"
Android:background="#FF00F0F0">
</Android.support.v4.view.ViewPager>
答えてくれたBrianとNicholasに大いに感謝します。この機能の最も明確な情報を追加し、いくつかの優れたプラクティスを紹介してください。
時々使用するViewPager
の非常に単純なサブクラスを構築しました。
/**
* View pager used for a finite, low number of pages, where there is no need for
* optimization.
*/
public class StaticViewPager extends ViewPager {
/**
* Initialize the view.
*
* @param context
* The application context.
*/
public StaticViewPager(final Context context) {
super(context);
}
/**
* Initialize the view.
*
* @param context
* The application context.
* @param attrs
* The requested attributes.
*/
public StaticViewPager(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// Make sure all are loaded at once
final int childrenCount = getChildCount();
setOffscreenPageLimit(childrenCount - 1);
// Attach the adapter
setAdapter(new PagerAdapter() {
@Override
public Object instantiateItem(final ViewGroup container, final int position) {
return container.getChildAt(position);
}
@Override
public boolean isViewFromObject(final View arg0, final Object arg1) {
return arg0 == arg1;
}
@Override
public int getCount() {
return childrenCount;
}
@Override
public void destroyItem(final View container, final int position, final Object object) {}
});
}
}
このクラスは、レイアウトからビューをロードするため、アダプターを必要としません。プロジェクトで使用するには、Android.support.v4.view.ViewPager
の代わりに使用します。
派手なものはすべて機能しますが、アダプターに煩わされる必要はありません。
ここにソリューションを追加したいと思います。フラグメントを使用する必要がない場合、PagerAdapter
の代わりにviews
をfragments
にアタッチするViewPager
を作成できます。
PagerAdapter
の代わりにFragmentPagerAdapter
を拡張
public class CustomPagerAdapter extends PagerAdapter {
private Context context;
public CustomPagerAdapter(Context context) {
super();
this.context = context;
}
@Override
public Object instantiateItem(ViewGroup collection, int position) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = null;
switch (position){
case 0:
view = MemoryView.getView(context, collection);
break;
case 1:
view = NetworkView.getView(context, collection);
break;
case 2:
view = CpuView.getView(context, collection);
break;
}
collection.addView(view);
return view;
}
@Override
public int getCount() {
return 3;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
}
ここで、views
で膨らませるviewpager
を返す3つのクラスを定義する必要があります。 CpuView
と同様に、MemoryView
およびNetworkView
クラスがあります。それぞれがそれぞれのレイアウトを膨らませます。
public class CpuView {
public static View getView(Context context, ViewGroup collection) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context
.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.debugger_cpu_layout, collection, false);
}
}
そして最後に、各ビューで膨張するレイアウト
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:textColor="#000000"
Android:text="CPU"/>
</LinearLayout>
P.S.:私がこの答えを書いた理由は、ここで提供されているすべてのソリューションが正常に機能しているように見えるが、PagerAdapterクラス自体のレイアウトを拡張しているためです。大規模なプロジェクトでは、レイアウトに関連する多くのコードが膨らんだ場合、メンテナンスが難しくなります。この例では、すべてのビューに個別のクラスと個別のレイアウトがあります。そのため、プロジェクトを簡単に保守できます。
私は@Nicholasの答えを詳しく述べたいと思います、あなたはIDによってビューを取得することができますまたは動的に追加された場合は、その位置が与えられたビューを直接取得するだけです
class WizardPagerAdapter extends PagerAdapter {
public Object instantiateItem(View collection, int position) {
View v = pager.getChildAt(position);
return v;
}
@Override
public int getCount() {
return 3;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
}