Viewpager+LinearLayout实现带索引的左右滑动
要实现的效果图:
主布局文件content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="me.bpazy.myapplication.MainActivity"
tools:showIn="@layout/activity_main">
<!--RelativeLayout存放一个ViewPager滚动,MarkLayout继承LinearLayout实现索引 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<me.bpazy.myapplication.MarkLayout
android:id="@+id/mark_layout"
android:layout_width="match_parent"
android:layout_height="@dimen/mark_height"
android:layout_alignParentBottom="true"
android:gravity="center"
android:orientation="horizontal" />
</RelativeLayout>
<TextView
android:paddingTop="8dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:text="@string/app_name" />
</LinearLayout>
自定义Fragment,相关的xml文件
public class MyFragment extends Fragment {
private String bm;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_fragment, null);
TextView textView = (TextView) view.findViewById(R.id.text);
textView.setText(bm);
return view;
}
public void setText(String bm) {
this.bm = bm;
}
public static MyFragment newInstance(String bm) {
MyFragment fragment = new MyFragment();
fragment.setText(bm);
return fragment;
}
}
<!--my_fragment.xml-->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/text"/>
</FrameLayout>
MarkLayout.java
public class MarkLayout extends LinearLayout {
private ImageView[] markImage; //存放索引View的数组
private int length = 1; //ViewPager的长度
//markImage的长宽
private int markWidth;
private int markHeight;
public MarkLayout(Context context) {
this(context, null);
}
public MarkLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MarkLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取索引的高度和宽度,这里mark_width和mark_height都是8dp
markWidth = (int)getResources().getDimension(R.dimen.mark_width);
markHeight = (int)getResources().getDimension(R.dimen.mark_height);
}
/**
* 设置当前索引的位置
* @param position 当前索引的位置
*/
public void setCurrentMark(int position) {
//先将索引的所有图标替换为未选中的状态
for (int i = 0; i < length; i++) {
markImage[i].setImageResource(R.mipmap.black);
}
//再将当前索引号的图标替换为选中的状态
markImage[position].setImageResource(R.mipmap.chosen);
}
/**
* 初始化索引
* @param length ViewPager的长度
*/
public void initResources(int length) {
this.length = length;
//根据长度确定需要多少个索引图标
markImage = new ImageView[length];
for (int i = 0; i < length; i++) {
//初始化ImageView并且将索引图标添加到this(MarkLayout)中
markImage[i] = new ImageView(getContext());
LayoutParams params = new LayoutParams(markWidth + 4, markHeight);
markImage[i].setLayoutParams(params);
addView(markImage[i]);
}
//设置当前索引为0,也就是第一个页面
setCurrentMark(0);
}
}
自定义FragmentPagerAdapter, 自定义OnPageChangeListener通知MarkLayout绘制索引
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private List<String> textList;
public MyFragmentPagerAdapter(FragmentManager fm, List<String> textList) {
super(fm);
this.textList = textList;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(textList.get(position));
}
@Override
public int getCount() {
return textList.size();
}
/**
* 自定义PageChangeListener
*/
static class MyPageChangeListener implements ViewPager.OnPageChangeListener {
private final MarkLayout markLayout;
/**
* 通过构造函数传入MarkLayout
* @param markLayout MarkLayout
*/
public MyPageChangeListener(MarkLayout markLayout) {
this.markLayout = markLayout;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
/**
* ViewPager滚动的时候调用markLayout的setCurrentMark通知MarkLayout重绘标志
* @param position ViewPager滚动到的界面
*/
@Override
public void onPageSelected(int position) {
markLayout.setCurrentMark(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//初始化ViewPager里要显示的数据
List<String> textList = new ArrayList<>();
textList.add("First Fragment");
textList.add("Second Fragment");
textList.add("Third Fragment");
textList.add("Fourth Fragment");
//初始化FragmentPagerAdapter, 并传入数据
MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), textList);
//初始化ViewPager
viewPager = (ViewPager) findViewById(R.id.view_pager);
assert viewPager != null;
viewPager.setAdapter(pagerAdapter);
//初始化MarkLayout
MarkLayout markLayout = (MarkLayout) findViewById(R.id.mark_layout);
//给viewPager添加PageChangeListener,并传入MarkLayout的实例,用来通知markLayout重绘索引
viewPager.addOnPageChangeListener(new MyFragmentPagerAdapter.MyPageChangeListener(markLayout));
assert markLayout != null;
//调用markLayout的initResources(List<String>)方法初始化索引
markLayout.initResources(textList.size());
}
}
可以将ViewPager里的TextView换成ImageView,这样就可以实现带索引的图片滑动: