18

更新:我可以使用以下布局在 Viewpager 中实现 3 个文本视图:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

       <TextView
          android:layout_height="wrap_content"
          android:layout_width="wrap_content"
          android:text="view 1"/>
       <TextView
          android:layout_height="wrap_content"
          android:layout_width="wrap_content"
          android:text="view 2"/>
       <TextView
          android:layout_height="wrap_content"
          android:layout_width="wrap_content"
          android:text="view 3"/>

    </android.support.v4.view.ViewPager>
</LinearLayout>

我想为这 3 个视图实现 ViewPager。我想在单个 xml 文件中有 viewpager 和这 3 个视图。每个页面包含每个文本视图。我看过一些示例,但每个页面都是使用单独的 xml 布局文件实现的。

如何在单个 xml 文件中为这 3 个视图实现 viewpager。如果可能,请向我提供示例代码或示例。

4

9 回答 9

55

您可以使用嵌套子视图的单个 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(View 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 == ((View) arg1);
        }
    }



    // Set the ViewPager adapter
    WizardPagerAdapter adapter = new WizardPagerAdapter();
    ViewPager pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);

我的问题是......这里的一些大师可以教我 ViewPager 是否有可能从 XML 读取子项并自动构建页面而不使用 instantiateItem()?

于 2012-10-24T04:05:36.973 回答
3

更新

此答案将显示在布局内设置 ViewPager 页面的优化和托管方式。

第1步

首先制作两个页面布局 XMLlayout_page_1.xmllayout_page_2.xml.

第2步

现在将所有页面布局包含在您的父布局中ViewPager

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        android:id="@+id/page_one"
        layout="@layout/layout_page_1" />

    <include
        android:id="@+id/page_two"
        layout="@layout/layout_page_2" />

</androidx.viewpager.widget.ViewPager>

第 3 步

现在从您的代码中,通过简单的步骤设置适配器

// find views by id
ViewPager viewPager = findViewById(R.id.viewpager);

CommonPagerAdapter adapter = new CommonPagerAdapter();

// insert page ids
adapter.insertViewId(R.id.page_one);
adapter.insertViewId(R.id.page_two);

// attach adapter to viewpager
viewPager.setAdapter(adapter);

就这样!您只需要一个用于所有 ViewPager 的通用适配器。

CommonPagerAdapter.java 类

public class CommonPagerAdapter extends PagerAdapter {
    private List<Integer> pageIds = new ArrayList<>();

    public void insertViewId(@IdRes int pageId) {
        pageIds.add(pageId);
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        return container.findViewById(pageIds.get(position));
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }

    @Override
    public int getCount() {
        return pageIds.size();
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }
}

重要的提示

最好使用片段而不是视图。您应该创建片段并使用它FragmentStatePagerAdapter来维护堆栈、生命周期和状态。您可以查看@this 答案以获取 using 的完整代码FragmentStatePagerAdapter

于 2018-11-16T10:31:09.737 回答
1

那是不可能的。你可以这样做

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/pager"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

然后创建单独的 xml 文件并这样做。例如:我将使用 xml 文件名为 ios_frag.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="50sp"/>
 </LinearLayout>
于 2014-01-28T06:36:38.313 回答
1

如果有人遇到同样的问题,我已经用一个适配器解决了这个问题,该适配器从您传递给它的任意视图组中提取页面视图。

    package com.packagename;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class ViewGroupPagerAdapter extends PagerAdapter {
    public ViewGroupPagerAdapter(ViewGroup viewGroup) {
        while (viewGroup.getChildCount() > 0) {
            views.add(viewGroup.getChildAt(0));
            viewGroup.removeViewAt(0);
        }
    }

    private List<View> views = new ArrayList<View>();

    @Override
    public Object instantiateItem(ViewGroup parent, int position) {
        View view = views.get(position);
        ViewPager.LayoutParams lp = new ViewPager.LayoutParams();
        lp.width = ViewPager.LayoutParams.FILL_PARENT;
        lp.height = ViewPager.LayoutParams.FILL_PARENT;
        view.setLayoutParams(lp);
        parent.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup parent, int position, Object object) {
        View view = (View) object;
        parent.removeView(view);
    }

    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
}

用法:

ViewPager viewPager=findViewById(...); // Retrieve the view pager
viewPager.setAdapter(new ViewGroupPagerAdapter(findViewById(R.id.id_of_your_view_group_where_you_store_the_pages)));
于 2014-06-04T19:52:34.630 回答
1

您可以继承ViewPager和覆盖onInflate.
此外,您将在布局编辑器中预览第一个 ViewPager 页面。
所有视图都保存在内存中,因此出于性能原因,您应该只在少量页面上使用它。

@Override protected void onFinishInflate() {
    int childCount = getChildCount();
    final List<View> pages = new ArrayList<>(childCount);
    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        Class<?> clazz = child.getClass();
        if (clazz.getAnnotation(DecorView.class) == null) {
            pages.add(child);
        }
    }
    for (View page : pages) {
        removeView(page);
    }
    setAdapter(new PagerAdapter() {
        @Override public int getCount() {
            return pages.size();
        }

        @Override public Object instantiateItem(ViewGroup container, int position) {
            container.addView(pages.get(position));
            return position;
        }

        @Override public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(pages.get((Integer)object));
        }

        @Override public boolean isViewFromObject(View view, Object object) {
            return pages.get((Integer)object) == view;
        }
    });
    super.onFinishInflate();
}
于 2017-01-06T12:34:13.500 回答
1
    viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
    viewPager.setAdapter(new MyPagerAdapter(rootView));
    viewPager.setOffscreenPageLimit(3); //or whatever you like

它缓存它并完美显示。

于 2017-07-18T14:49:51.693 回答
0

将此添加到您的 xml 布局文件中

<android.support.v4.view.ViewPager 
    android:id="@+id/view_pager"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

创建 3 Fragments 并TextView为每个片段添加每个。然后创建一个子类化的适配器PagerAdapter

一个很好的例子可以在这里找到

于 2012-09-06T07:51:03.823 回答
0

如何在单个 xml 文件中为这 3 个视图实现 viewpager。

对不起,但那是不可能的。

于 2012-09-06T14:22:19.920 回答
-3

很简单:在你的文件中添加一个 ViewPager 并放入你的 3 TextView...

于 2012-09-06T07:36:05.350 回答