Android:如何在单个 xml 文件中实现 viewpager 和视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12295066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: How to implement viewpager and views in single xml file
提问by Dileep Perla
UPDATED : Can I use the following layout to implement 3 textviews in Viewpager :
更新:我可以使用以下布局在 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>
I want to implement the ViewPager for these 3 views. and i want to have viewpager and those 3 views in single xml file. Each page contains each textview. I have seen some examples but each page was implement using separate xml layout file.
我想为这 3 个视图实现 ViewPager。我想在单个 xml 文件中有 viewpager 和这 3 个视图。每个页面都包含每个文本视图。我看过一些例子,但每个页面都是使用单独的 xml 布局文件实现的。
How can I implement the viewpager for these 3 views in a single xml file. If possible please provide me a sample code or example.
如何在单个 xml 文件中为这 3 个视图实现 viewpager。如果可能,请为我提供示例代码或示例。
采纳答案by CommonsWare
How can I implement the viewpager for these 3 views in a single xml file.
如何在单个 xml 文件中为这 3 个视图实现 viewpager。
Sorry, but that is not possible.
对不起,但那是不可能的。
回答by jjalonso
You can use a single XML layout nesting the children views.
您可以使用单个 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>
BUT... you need handle this with an adapter also. Here we return the finded view ID without inflate any other layout.
但是...您还需要使用适配器处理此问题。在这里,我们返回找到的视图 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);
My question is... Some Guru here can teach me if is possible that the ViewPager read the children from XML and auto build the pages without use the instantiateItem()?
我的问题是......这里的一些大师可以教我ViewPager是否可以从XML读取子项并在不使用instantiateItem()的情况下自动构建页面?
回答by Khemraj
Update
更新
This answer will show optimised and managed way to set ViewPager pages inside layout.
此答案将显示在布局内设置 ViewPager 页面的优化和托管方式。
Step 1
第1步
First make two pages Layouts XML layout_page_1.xml
and layout_page_2.xml
.
首先制作两页布局 XMLlayout_page_1.xml
和layout_page_2.xml
.
Step 2
第2步
Now include all pages layout in your parent layout ViewPager
.
现在在您的父布局中包含所有页面布局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>
Step 3
第 3 步
Now from your code, set adapter in simple steps
现在从您的代码中,通过简单的步骤设置适配器
// 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);
That's All! You need only a common adapter for all ViewPagers.
就这样!您只需要一个适用于所有 ViewPagers 的通用适配器。
CommonPagerAdapter.java class
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;
}
}
Important Note
重要的提示
It is better to use Fragments instead of Views. You should create Fragments and use FragmentStatePagerAdapter
to maintain stack, lifecycle and states. You can see @this answerfor complete code of using FragmentStatePagerAdapter
.
最好使用 Fragments 而不是 Views。您应该创建 Fragments 并用于FragmentStatePagerAdapter
维护堆栈、生命周期和状态。您可以在@this 上查看完整的 using 代码FragmentStatePagerAdapter
。
回答by Khemraj
thats impossible .you can do it like these
那是不可能的。你可以这样做
<?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" />
then create seperate xml file and do it like this.for eg:i am gonna use the xml file name is ios_frag.xml :
然后创建单独的 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>
回答by Aron Lorincz
Just if anyone faces the same problem, I've solved it with an adapter which extracts the page views from an arbitrary viewgroup that you pass to it.
如果有人遇到同样的问题,我已经使用适配器解决了它,该适配器从您传递给它的任意视图组中提取页面视图。
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;
}
}
Usage:
用法:
ViewPager viewPager=findViewById(...); // Retrieve the view pager
viewPager.setAdapter(new ViewGroupPagerAdapter(findViewById(R.id.id_of_your_view_group_where_you_store_the_pages)));
回答by tango24
You can subclass ViewPager
and override onInflate
.
Moreover, you will get a preview of the first ViewPager page in the Layout Editor.
All views are kept in memory so for performance reasons you should only use this with a small number of pages.
您可以子类化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();
}
回答by Alp Altunel
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(rootView));
viewPager.setOffscreenPageLimit(3); //or whatever you like
it caches it and shows perfectly.
它缓存它并完美显示。
回答by chip
add this in your xml layout file
将此添加到您的 xml 布局文件中
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
create 3 Fragment
s and add each TextView
for every fragment. Then create an adapter that subclassed PagerAdapter
创建 3 Fragment
s 并TextView
为每个片段添加每个。然后创建一个子类化的适配器PagerAdapter
A good example can be found here
一个很好的例子可以在这里找到
回答by arnouf
Simply : add a ViewPager in your file and put inside your 3 TextView...
简单地:在您的文件中添加一个 ViewPager 并放入您的 3 TextView ...