ViewPager+Fragment添加一行若干小红球滚动指示器指示当前ViewPager翻阅位置(可供第三方使用的类)

简介: 效果图如下:ViewPager+Fragment添加一行若干小红球滚动指示器指示当前ViewPager翻阅位置(可供第三方使用的类)。

效果图如下:


ViewPager+Fragment添加一行若干小红球滚动指示器指示当前ViewPager翻阅位置(可供第三方使用的类)。

类似现在通用的新闻客户端头部,会放置几张图片供新闻阅读者翻阅,同时放置一行小圆球根据用户翻阅的位置相应的滚动,标识出当前第几页。

该项目开放出几个用以重载的方法函数供第三方使用:

protected Fragment getFragmentAt(int pos) {
		return null;
	}

	protected int getItemsCount() {
		return 0;
	}
	
	protected	String	getDescriptionAt(int pos){
		return	null;
	}


测试用的主MainActivity.java (不是重点,仅仅用以测试)

package zhangphil.viewpager_fragment;

import java.util.ArrayList;
import java.util.Random;

import com.example.viewpager_fragment.R;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends FragmentActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Fragment newFragment = new HowToUseThisView();
		FragmentTransaction transaction = getSupportFragmentManager()
				.beginTransaction();
		transaction.replace(R.id.fragment, newFragment);
		transaction.commit();
	}

	public static class HowToUseThisView extends
			ViewPagerAndFragmentWithCircleIndicator {

		private ArrayList<Fragment> mArrayList;

		// 主要用以标记Fragment,没特别意义
		private int id = 0;

		// ViewPager的元素个数。
		private int item_count = 0;

		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			mArrayList = new ArrayList<Fragment>();

			// 测试用的。假设生成随机个数的Fragment。
			Random rand = new Random();
			item_count = rand.nextInt(10);
		}

		@Override
		protected Fragment getFragmentAt(int pos) {

			Fragment fragment = null;

			try {
				fragment = mArrayList.get(pos);
			} catch (Exception e) {
				Log.d(this.getClass().getName(), "队列中不存在,创建新Fragment");
			}

			if (fragment == null) {
				fragment = new TestFragment();
				((TestFragment) fragment).setID(id++);
				mArrayList.add(fragment);
			}

			return fragment;
		}

		@Override
		protected int getItemsCount() {
			return item_count;
		}

		@Override
		protected String getDescriptionAt(int pos) {
			//实际使用过程中,可根据每个不同的Fragment返回不同的描述文本
			return pos + "";
		}
	}

	//
	// 仅仅用于测试的Fragment,在ViewPager中加载
	//
	public static class TestFragment extends Fragment {

		private int id = 0;

		public void setID(int id) {
			this.id = id;
		}

		public int getID() {
			return id;
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {

			TextView tv = new TextView(getActivity());
			String str = "序号: " + getID();
			tv.setTextColor(Color.LTGRAY);
			tv.setText(str);
			tv.setTextSize(60);
			tv.setGravity(Gravity.CENTER);

			return tv;
		}
	}
}

MainActivity.java所要的布局文件 activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
   
    <FrameLayout 
   		android:id="@+id/fragment"  
        android:layout_width="match_parent"
    	android:layout_height="match_parent">	
    </FrameLayout>
    
    
 </LinearLayout>



重点是 ViewPagerAndFragmentWithCircleIndicator.java

package zhangphil.viewpager_fragment;

import com.example.viewpager_fragment.R;

import zhangphil.libs.view.CircleIndicatorView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class ViewPagerAndFragmentWithCircleIndicator extends Fragment {

	private MyFragmentPagerAdapter mPagerAdapter;
	private ViewPager mViewPager;
	private CircleIndicatorView mCircleIndicatorView;
	private	TextView circleIndicatorView_TextView;

	private Handler handler;
	private final int MESSAGE_WHAT_DRAW_CIRCLE = 100;

	public void notifyDataSetChanged() {
		mPagerAdapter.notifyDataSetChanged();
	}

	protected Fragment getFragmentAt(int pos) {
		return null;
	}

	protected int getItemsCount() {
		return 0;
	}
	
	protected	String	getDescriptionAt(int pos){
		return	null;
	}
	

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View mView = inflater.inflate(R.layout.viewpager_fragment, null);

		mViewPager = (ViewPager) mView.findViewById(R.id.viewpager);
		mPagerAdapter = new MyFragmentPagerAdapter(getFragmentManager());
		mViewPager.setAdapter(mPagerAdapter);
		mViewPager
				.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

					@Override
					public void onPageSelected(int pos) {
						set(pos);
					}

					@Override
					public void onPageScrolled(int arg0, float arg1, int arg2) {

					}

					@Override
					public void onPageScrollStateChanged(int arg0) {

					}
				});

		mCircleIndicatorView = (CircleIndicatorView) mView
				.findViewById(R.id.circleIndicatorView);
		mCircleIndicatorView.drawCircleView(mPagerAdapter.getCount(), 0);
		
		//初始化红色小圆球的 位置和文本描述
		circleIndicatorView_TextView=(TextView) mView.findViewById(R.id.circleIndicatorView_TextView);
		circleIndicatorView_TextView.setText(getDescriptionAt(0));
		
		handler = new Handler() {
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				switch (msg.what) {
				case MESSAGE_WHAT_DRAW_CIRCLE:
					
					mCircleIndicatorView.drawCircleView(mPagerAdapter.getCount(),mViewPager.getCurrentItem());
					
					break;
				}
			};
		};

		return mView;
	}

	private void set(int pos) {
		mViewPager.setCurrentItem(pos, true);
		circleIndicatorView_TextView.setText(getDescriptionAt(pos));
		handler.sendEmptyMessage(MESSAGE_WHAT_DRAW_CIRCLE);
	}
	
	private class MyFragmentPagerAdapter extends FragmentPagerAdapter {

		public MyFragmentPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int pos) {
			return	getFragmentAt(pos);
		}

		@Override
		public int getCount() {
			return	getItemsCount();
		}

		@Override
		public void notifyDataSetChanged() {
			super.notifyDataSetChanged();
			handler.sendEmptyMessage(MESSAGE_WHAT_DRAW_CIRCLE);
		}
	}
}

ViewPagerAndFragmentWithCircleIndicator.java需要的布局文件 viewpager_fragment.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:orientation="vertical" >
    
   <FrameLayout 
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dip"
        android:orientation="horizontal"
        android:layout_gravity="bottom" >

        <TextView
            android:id="@+id/circleIndicatorView_TextView"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:gravity="left"
            android:textColor="#FF0000"
            android:layout_weight="1"
            android:singleLine="true"
            android:text="" />
        
        <zhangphil.libs.view.CircleIndicatorView
            android:id="@+id/circleIndicatorView"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="0.382"/>
        
    </LinearLayout>

</FrameLayout>

</LinearLayout>



以及用以绘制红色小圆球的 CircleIndicatorView.java

package zhangphil.libs.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CircleIndicatorView extends View { 
	
    public CircleIndicatorView(Context context, AttributeSet attrs){   
    	       super(context, attrs);  
    }
    
    private	int	gap=20;//各个横向排列的小球间距
	public	void	setCirlceGap(int gap){
	    	this.gap=gap;
	}
	public	int	getCirlceGap(){
	    	return	gap;
	}
    
    private	int	padding=20;
    public	void	setPadding(int padding){
    	this.padding=padding;
    }
    public	int	getPadding(){
    	return	padding;
    }
    
    private	int	circle_normal_radius=5; //普通小球半径
    public	void	setNormalCircleRadius(int radius){
    	this.circle_normal_radius=radius;
    }
    public	int	getNormalCircleRadius(){
    	return	circle_normal_radius;
    }
    
    private	int	circle_selected_radius=7; //被选择的小球半径
    public	void setSelectedCircleRadius(int radius){
    	this.circle_selected_radius=radius;
    } 
    public	int	getSelectedCircleRadius(){
    	return	circle_selected_radius;
    }
    
    private	int	count=0;
    public	void	setCircleCount(int count){
    	this.count=count;
    }
    public	int	getCircleCount(){
    	return	count;
    }

    private	int	pos=0;
    public	void	setCircleSelectedPosition(int pos){
    	this.pos=pos;
    }
    public	int	getCircleSelectedPosition(){
    	return	pos;
    }
    
    public	void	drawCircleView(){
    	this.invalidate();
    }
    
    public	void	drawCircleView(int count,int circleSelectedPosition){
    	setCircleCount(count);
    	setCircleSelectedPosition(circleSelectedPosition);
    	
    	this.invalidate();
    }
    
    private	int	circleSelectedColor=Color.RED;
    public	void	setCircleSelectedColor(int color){
    	circleSelectedColor=color;
    }
    public	int	getCircleSelectedColor(){
    	return	circleSelectedColor;
    }
    
    private	int	circleUnSelectedColor=Color.LTGRAY;
    public	void	setCircleUnSelectedColor(int color){
    	circleUnSelectedColor=color;
    }
    public	int	getCircleUnSelectedColor(){
    	return	circleUnSelectedColor;
    }

    
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas); 
        
        Paint p = new Paint();  
        p.setAntiAlias(true);
        
        int w=this.getWidth();
        int h=this.getHeight();
        
        //因为是自右往左绘制小圆圈,需要转化pos的位置。
      int translate_pos=getCircleCount()-getCircleSelectedPosition()-1;
       
      //如果居中绘制则使用start_x,但需要依次递加x坐标轴位置值。
      //int start_x=(w-(CIRCLE_GAP*(getCircleCount()-1)))/2;
        
        for(int i=0;i<getCircleCount();i++){
        	int r=getNormalCircleRadius();
        	
        	if(i==translate_pos){
        		r=getSelectedCircleRadius();
        		p.setColor(getCircleSelectedColor());
        	}
        	else{
        		r=getNormalCircleRadius();
        		p.setColor(getCircleUnSelectedColor()); 
        	}
        	
        	//自右向左绘制。从最右边往左边绘制小球
        	//如果从该自定制的View左边绘制,直接将 x=0即可。
        	canvas.drawCircle(w-i*getCirlceGap()-getPadding(), h/2, r, p);
        }
    } 
}  



相关文章
|
XML Java Android开发
Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar
Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar
239 0
|
iOS开发
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
276 0
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
ViewPager如何区分自动切换和手势滑动切换
ViewPager是一个很常见的组件,不仅支持收拾滑动切换页面,我们还可以通过`viewPager.setCurrentItem(index)`来切换到指定的页面,那么他们如何区分呢? 我们知道ViewPager可以添加`ViewPager.OnPageChangeListener`监听器,可以监听切换的状态。通过观察`ViewPager.OnPageChangeListener#onPageScrollStateChanged(int state)`方法中state的输出,发现了手势切换和自动切换的规律。
BottomNavigationView使用,配合ViewPager、修改图标大小、去掉文字等
BottomNavigationView使用,配合ViewPager、修改图标大小、去掉文字等
667 0
BottomNavigationView使用,配合ViewPager、修改图标大小、去掉文字等
tablayout支持改变选中文字大小,支持左右滑动,支持viewpager,支持三角可移动指示器
TabLayout [简书地址] (https://www.jianshu.com/p/2c3f868266e8) 基于大神的FlycoTabLayout 传送地址和基本用法 用法和属性和这个库一样 效果图如下 Gif_20180828_142709.
2489 0
|
Android开发 容器
一行代码引入 ViewPager 无限循环 + 页码显示
(出处:http://www.cnblogs.com/linguanh)   前序:   网上的这类 ViewPager 很多,但是很多都不够好,体现在 bug多、对少页面不支持,例如1~2张图片、功能整合不全(无限+页码)等等,本类由我从零到无完成的,基本已找完 bug,注释丰富,方便大家理解。
1070 0