我可以使用视图寻呼机与视图(而不是片段)

我使用 ViewPagerFragments之间滑动,但是我可以使用 ViewPagerViews简单的 XML 布局之间滑动吗?

这是我的页面 Adapter的 ViewPager,用于在片段之间滑动:

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

如何修改代码以使用视图而不是片段?

84163 次浏览

用这个例子

可以使用嵌套子视图的单个 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);

您需要覆盖这两个方法,而不是 getItem():

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

我想详细说明一下@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);
}
}

基于以上的答案,为了达到这个目的,我上了以下课程(我希望) :

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

所有这些花哨的东西仍然可以工作,但是您不需要为适配器而烦恼。

我想在这里加上我的解决方案。假设您不需要使用片段,您仍然可以创建一个将 views而不是 fragments附加到 ViewPagerPagerAdapter

扩展 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);
}
}

现在您需要定义三个类,它们将返回要在 viewpager中充气的 views。类似于 CpuView你将有 MemoryViewNetworkView类。他们每个人将膨胀各自的布局。

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>

PS: 我写这个答案的原因是因为这里提供的所有解决方案似乎都工作得很好,但是它们在 PagerAdapter 类本身中扩展了布局。对于大型项目来说,如果它们的代码与布局相关的代码太多,就很难维护。现在在这个例子中,所有的视图都有单独的类和单独的布局。因此,项目可以很容易地维护。

是的... 你可以在视图页中使用视图代替碎片。 在这里你可以找到完整的例子,它将帮助你实现没有片段的 Viewpager。

Https://www.bignerdranch.com/blog/viewpager-without-fragments/

如果你使用 ViewPager2,根据文档,你可以使用一个标准的回收视图。适配器:

如果您计划使用片段作为页面,请实现 如果页面是视图,则实现 RecyclerView.Adapter一如既往。

Https://developer.android.com/reference/androidx/viewpager2/widget/viewpager2#setadapter (androidx。回收视图。小部件。回收视图。适配器)

在 ViewPager2中,根本不需要使用片段。 只需创建一个适配器,就像您创建回收视图适配器一样。 设置为 ViewPager2。

然而,需要记住的一点是,要充气的视图的布局高度应该是 match _ father,而不是像对回收视图那样包装内容。

Snap 的行为也是相同的。