码迷,mamicode.com
首页 > 移动开发 > 详细

android 打造变化多端的SeekBar(垂直和水平)

时间:2016-02-27 11:07:35      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

SeekBar相信用的人不是很多,一般都是用水平SeekBar就可以了。但是之前项目中考虑使用垂直的SeekBar,就要继承重写SeekBar才能用。而垂直SeekBar在百度搜了一下,关于这方面文章还是很少,有一些还是不全面。我又去了github找了一下,找到了一个垂直的效果以及源码,我就写了一个滚动SeekBar翻页listview的数据效果。所以这篇博客中源码下载中,有三个项目源码,干货多多。

下载地址:http://download.csdn.net/detail/qq_16064871/9445535

1、先看一下水平SeekBar

这种是用系统SeekBar,是水平的。我在滚动SeekBar上面加了页码提示。滚动页码时候也可以翻页listview的数据。先看效果。

技术分享

看着上面效果还是很不错吧,觉得很赞。接下来看看原理。

其实这个原理很简单,这个滚动SeekBar以及listview管理都是一系列的序号,就是多少项数据的索引吧。用一个list记住每一页的表头第一项的索引值,因为每一页数据都是固定。就比如每一页数据是30,那么第一页第一项索引就是0,第二页是30,第三页是60.。。。以此类推,还有根据你滑动进度条,获得那一页数据,再根据这一页表头索引加上30就是这一页的数据。所以管理都是序号或者说索引。所以所以最后获取数据是这样的mArrayList.get(mPageItemsIndex.get(position).intValue())。而这个就是每一页数据索引值mPageItemsIndex.get(position).intValue()。好了说了那么多,看代码吧。

先看这个public class LevelPageSeekBar extends SeekBar

package com.org.view;

import com.org.pageseekbar.R;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.SeekBar;
import android.widget.TextView;
//自定义页码进度条
public class LevelPageSeekBar extends SeekBar {
	private QuickAction mSeekBarTipsQuickAction;
	private int mPageCount = 0;
	private boolean mIsTouch = false;
	private TextView mTipsTitle;
	private OnSeekBarPageChangeListener mBarPageChangeListener;
	
	public LevelPageSeekBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		mSeekBarTipsQuickAction = new QuickAction(context, QuickAction.HORIZONTAL);
		ActionItem tipsItem      = new ActionItem(0, context.getResources().getString(R.string.Move), null);
		tipsItem.setIcon(null);
		mSeekBarTipsQuickAction.addActionItem(tipsItem);
		mTipsTitle = (TextView)mSeekBarTipsQuickAction.GetActionItemsGroup().getChildAt(0).findViewById(R.id.tv_title);
		
		//设置系统进度条的监听
		setOnSeekBarChangeListener(mSeekBarChangeListener);
		//最大页码是10000
		setMax(10000);
	}
	
	//进度条改变的接口
	public interface OnSeekBarPageChangeListener {
		public abstract void setSeekBarScrolling(TextView tips, int page);
		public abstract void setSeekBarPageChanged(int page);
	}
	
	//注册接口
	public void setSeekBarPageChangeListener(OnSeekBarPageChangeListener listener) {
		mBarPageChangeListener = listener;
	}
	
	//设置进度条页数
	public void setPagesCount(int count) {
		mPageCount = count;
	}
	
	//设置不显示弹出第几页提示
	public void setHideSeekPopWindow() {
		mSeekBarTipsQuickAction.dismiss();
	}
	
	private int getProgressIsPageIndex(int progress, int max) {
		if (mPageCount < 2) {
			if (progress == 0) return 0;
			else return 1;
		}
		if (progress == 0) return 0;
		// 获取每一块的进度值
		int progressSizeEveryPage = getMax()/(mPageCount-1);
		for (int i = 1; i < mPageCount; i++) {
			if (progress <= (i)*progressSizeEveryPage && progress > ((i-1)*progressSizeEveryPage)) {
				if (progress > (2*i-1)*progressSizeEveryPage/2 ) return i;
				else return i-1;
			}
		}
		return mPageCount-1;
	}

	//外面调用上下按键翻页,需要同时滚动进度条效果
	public void setProgressSpecialPage(int pageIndex, int count) {
		if (count <= 1) {
			setProgress(0);
			return;
		}
		
		mPageCount = count;
		if (pageIndex < 0 || pageIndex >= mPageCount) return;

		int progressSizeEveryPage = getMax()/(mPageCount-1);
		setProgress( progressSizeEveryPage*pageIndex);
	}
	
	//弹出当前显示第几页的提示
	private void showSeekPopWindow() {
		if (mSeekBarTipsQuickAction == null) return;
		// 获取每一刻度的宽度
		float thumb_x = ((float)this.getWidth() - 44)/(float)this.getMax();
		// 获取控件的屏幕位置
		int[] location = new int[2];
		this.getLocationOnScreen(location);
		
		int x = (int) ((float)thumb_x*(float)getProgress()) + 22;
		
		if (mBarPageChangeListener != null) 
			mBarPageChangeListener.setSeekBarScrolling(mTipsTitle, getProgressIsPageIndex(getProgress(), getMax()));
		mSeekBarTipsQuickAction.show(this, (int)(x + location[0]), location[1]);
	}
	
	//系统进度条的监听方法
	private OnSeekBarChangeListener mSeekBarChangeListener = new OnSeekBarChangeListener() {
		@Override
		public void onStopTrackingTouch(SeekBar arg0) {
			mIsTouch = false;
			setHideSeekPopWindow();
		}
		
		@Override
		public void onStartTrackingTouch(SeekBar arg0) {
			mIsTouch = true;
		}
		
		@Override
		public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
			if (mIsTouch) showSeekPopWindow();
			if (mBarPageChangeListener != null) 
				mBarPageChangeListener.setSeekBarPageChanged( getProgressIsPageIndex(getProgress(), getMax()));
		}
	};
}

再看怎么调用或者说使用。看MainActivity

package com.org.pageseekbar;

import java.util.ArrayList;

import com.org.view.LevelPageSeekBar;
import com.org.view.LevelPageSeekBar.OnSeekBarPageChangeListener;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity 
implements OnSeekBarPageChangeListener,OnClickListener{

	//页码进度条
	private LevelPageSeekBar mPageSeekBar;
	//数据源
	private ArrayList<String> mArrayList;
	// 一页最多多少条数据
	protected int mMaxShowLinesPage = 20;
	// 当前是第几页
	protected int mCurrentSelectPageIndex = 0;
	// 当前有多少页
	protected int mPagesCount = 0;
	// 当前的有效记录数
	protected int mRecordCount = 0;
	// 存放每页数据第一条数据的索引
	protected ArrayList<Integer> mEveryPageOffestArray = new ArrayList<Integer>();
	// 当前页面的每一项的偏移数据 方便检索数据和删除数据
	protected ArrayList<Integer> mPageItemsIndex = new ArrayList<Integer>();
	//listview的适配器
	protected ListViewAdapter mAdapter;
	//测试数据的条数
	private int mnTestCount = 530;	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		initDatas();
		initView();
	}

	private void initDatas() {
		if (mArrayList == null) {
			mArrayList = new ArrayList<String>();
			for (int i = 0; i < mnTestCount; i++) {
				mArrayList.add("第   " + String.valueOf(i) + " 项");
			}
		}
	}

	private void initView() {
		mPageSeekBar = (LevelPageSeekBar)findViewById(R.id.seekBar);
		mPageSeekBar.setSeekBarPageChangeListener(this);
		
		Button imageviewUp = (Button)findViewById(R.id.imageviewUp);
		imageviewUp.setOnClickListener(this);
		Button imageviewDown = (Button)findViewById(R.id.imageviewDown);
		imageviewDown.setOnClickListener(this);
	    ListView listView = (ListView)findViewById(R.id.listView1);
	    mAdapter = new ListViewAdapter(this);
	    listView.setAdapter(mAdapter);
	    
	    initResetListView(0);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.imageviewUp:
			setPrePage();
			break;
		case R.id.imageviewDown:
			setAftPage();
			break;
		default:
			break;
		}
	}

	//初始化进度条管理数据显示
	protected void initResetListView(int pageIndex) {
		mRecordCount = mArrayList.size();
		
		// 计算有多少页数据
	    mPagesCount = mRecordCount/mMaxShowLinesPage + (mRecordCount%mMaxShowLinesPage == 0 ? 0 : 1);
	    
	    // 判断 页面数目是2的时候, 简化为1页
	    if (mPagesCount == 2) {
	    	mMaxShowLinesPage = mMaxShowLinesPage * 2;
	    	mPagesCount = 1;
	    } else {
	    	mMaxShowLinesPage = 20;
	    }
		
		// 设置当前选中也为0
		mCurrentSelectPageIndex = pageIndex;
		if (mCurrentSelectPageIndex >= mPagesCount)
			mCurrentSelectPageIndex = mPagesCount - 1;
		//刷新每一页的首偏移
		setResetEveryPageOffestArray();
		//根据首偏移,得到这一页偏移序号
	    setResetPageItemsIndex(mCurrentSelectPageIndex);
		//上下按键翻页,需要同时滚动进度条效果.如果只有两页数据,不显示进度条
	    setSelectPageControl(mCurrentSelectPageIndex, mPagesCount,false);
	    
		//总共几页,设置到进度条控件
	    mPageSeekBar.setPagesCount(mPagesCount);
	}
	
	//刷新每一页的首偏移
	protected void setResetEveryPageOffestArray() {
		int nValidItemNums = 0;
		mEveryPageOffestArray.clear();
		//记住每页的首偏移序号
		for (int i = 0; i < mPagesCount; i++) {
			int nRecordIndex = GetCountSpecialPage(i);
				mEveryPageOffestArray.add(nValidItemNums);
				nValidItemNums = nValidItemNums + nRecordIndex;
		}
		
		if (nValidItemNums != mRecordCount) {
			mRecordCount = nValidItemNums;
			// 计算有多少页数据
		    mPagesCount = mRecordCount/mMaxShowLinesPage + (mRecordCount%mMaxShowLinesPage == 0 ? 0 : 1);
		}
	}
	
	//根据首偏移,得到这一页偏移序号
	protected void setResetPageItemsIndex(int pageIndex) {
		if (pageIndex >= mEveryPageOffestArray.size()) return;
		int pageItemsCount = GetCountSpecialPage(pageIndex);
		int nRecordIndex = mEveryPageOffestArray.get(pageIndex).intValue();
		mPageItemsIndex.clear();
		//首偏移开始累加
		for(int i = nRecordIndex; i < pageItemsCount + nRecordIndex; i++) {
			mPageItemsIndex.add(i);
		}
		
		//刷新listview的适配器
		if (mAdapter != null) {
			mAdapter.notifyDataSetChanged();
		}
	}
	
	// 获取当前页面多少数据
	protected int GetCountSpecialPage(int nPage) {
		if (nPage < 0) return 0;
		if(nPage < (mPagesCount-1)) return mMaxShowLinesPage;
		//如果是最后一页,就是总的数据减去前面几页*每一页的数据
		//因为页码是从0开始,所以这里是最后一页
		if (nPage == mPagesCount - 1) return mRecordCount - mMaxShowLinesPage*(mPagesCount-1);
		return 0;
	}
	
	//上一页
	protected void setPrePage() {
		if (mCurrentSelectPageIndex == 0) return;
		mCurrentSelectPageIndex -= 1;
		//根据首偏移,得到这一页偏移序号
		setResetPageItemsIndex(mCurrentSelectPageIndex);
		// 翻页控件
		setSelectPageControl(mCurrentSelectPageIndex, mPagesCount,true);
	}
	
	//下一页
	protected void setAftPage() {
		if (mCurrentSelectPageIndex == (mPagesCount-1)) return;
		mCurrentSelectPageIndex += 1;
		//根据首偏移,得到这一页偏移序号
		setResetPageItemsIndex(mCurrentSelectPageIndex);
		// 翻页控件
		setSelectPageControl(mCurrentSelectPageIndex, mPagesCount,true);
	}
	
	//进度条滑动改变的数据,进行刷新
	protected void setPageChanged(int index, boolean isSetProgress) {
		if (index < 0 || index >= mPagesCount || mCurrentSelectPageIndex == index) return;
		mCurrentSelectPageIndex = index;
		
		// 刷新每一项的索引数据
		setResetPageItemsIndex(mCurrentSelectPageIndex);
		// 翻页控件
		setSelectPageControl(mCurrentSelectPageIndex, mPagesCount, isSetProgress);
	}

	//上下按键翻页,需要同时滚动进度条效果.如果只有两页数据,不显示进度条
	protected void setSelectPageControl(int index, int count, boolean isSet) {
		View selectPageBar = findViewById(R.id.layoutShow);
		if (selectPageBar != null) {
			//如果只有两页数据,不显示进度条
		if (count <= 1) selectPageBar.setVisibility(View.GONE);
		else selectPageBar.setVisibility(View.VISIBLE);
		//上下按键翻页,需要同时滚动进度条效果
		if (mPageSeekBar != null && isSet == true)
			mPageSeekBar.setProgressSpecialPage(mCurrentSelectPageIndex, mPagesCount);			
		}
	}
	
	//弹出滑动第几页显示
	@Override
	public void setSeekBarScrolling(TextView tips, int page) {
		if (tips == null) return;
		String tip_0 = String.format(getString(R.string.CurrentPageTipsFormate), page+1);
		String tip_1 = String.format(getString(R.string.CurrentPageTipsFormate2), mPagesCount);
		tips.setText(tip_0 + "/" + tip_1);
	}

	//进度条滑动改变的数据,进行刷新
	@Override
	public void setSeekBarPageChanged(int page) {
		setPageChanged(page, false);
	}
	
	private class ViewHolder{
		TextView textView;
	}
	
	private class ListViewAdapter extends BaseAdapter{
		private Context mContext;
		private LayoutInflater mLayoutInflater;
		public ListViewAdapter(Context context) {
			mContext = context;
			mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}
		@Override
		public int getCount() {
			return mPageItemsIndex.size();
		}

		@Override
		public Object getItem(int position) {
			return 0;
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder vHolder = null;
			if (convertView == null) {
				vHolder = new ViewHolder();
				convertView = mLayoutInflater.inflate(R.layout.listview_item, null);
				vHolder.textView = (TextView)convertView.findViewById(R.id.textView1);
				convertView.setTag(vHolder);
			}else {
				vHolder = (ViewHolder) convertView.getTag();
			}
			vHolder.textView.setText(mArrayList.get(mPageItemsIndex.get(position).intValue()));
			return convertView;
		}
	}
	
}
至于弹出显示页码的效果,这个代码有点多,就不一一展示了。有兴趣下载本博客源码。

弹出显示页码的效果有兴趣可以看看这个,也是差不多的:Android 单击listview弹出popupwindow弹出框

2、现在看看我在github上找的垂直SeekBar效果

技术分享

这里面原理是这样的。你的进度条旋转了,你的画布也要旋转。还有你的Thumb这要重新调转位置,跟着一起滑动。有两种情况,从上图都可以看出了。一种是从上而下,还有一种就是从下而上。

从上而下那个调整画布是这样的,还有一些计算。。。看源码也是继承SeekBar

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    //初始值从上往下
    protected void onDraw(Canvas c) {
        c.rotate(90);
        c.translate(0, -getWidth());

        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
            	int i=0;
            	i=getMax() - (int) (getMax() * event.getY() / getHeight());
                setProgress(100-i);
                Log.i("Progress",getProgress()+"");
                onSizeChanged(getWidth(), getHeight(), 0, 0);
                break;

            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }
那么从下往上滑动,肯定要反过来旋转了

   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }


    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }
    
    //初始值从下往上
    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(),0);

        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
            	int i=0;
            	i=getMax() - (int) (getMax() * event.getY() / getHeight());
                setProgress(i);
                Log.i("Progress",getProgress()+"");
                onSizeChanged(getWidth(), getHeight(), 0, 0);
                break;

            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }
其实就是这么简单的。

3、看看我写的垂直SeekBar效果

还是一样,先看效果。

技术分享


也是对这个listview的数据管理的。就是没有弹出页码的提示,因为弹出感觉不好看,就删了。

看源码:VerticalPageSeekBar extends SeekBar

package com.vertical.view;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;
//自定义页码进度条
public class VerticalPageSeekBar extends SeekBar {
	private int mPageCount = 0;
	private OnSeekBarPageChangeListener mBarPageChangeListener;
	
    public VerticalPageSeekBar(Context context) {
        super(context);
    }

    public VerticalPageSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
	public VerticalPageSeekBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		//设置系统进度条的监听
		super.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			
			@Override
			public void onStopTrackingTouch(SeekBar arg0) {
			}
			
			@Override
			public void onStartTrackingTouch(SeekBar arg0) {
			}
			
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				if (mBarPageChangeListener != null) 
					//接口回调
					mBarPageChangeListener.setSeekBarPageChanged( getProgressIsPageIndex(progress, getMax()));
			}
		});
		
		setMax(1000);
	}
	
	//进度条改变的接口
	public interface OnSeekBarPageChangeListener {
		public abstract void setSeekBarPageChanged(int page);
	}
	
	//注册接口
	public void setSeekBarPageChangeListener(OnSeekBarPageChangeListener listener) {
		mBarPageChangeListener = listener;
	}
	
	//Thumb的变化情况
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }

    //测量宽度也需要旋转
    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    //画布旋转90
    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(),0);

        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
            	int i=0;
            	//设置y值为进度条的值
            	i=getMax() - (int) (getMax() * event.getY() / getHeight());
                setProgress(i);
                onSizeChanged(getWidth(), getHeight(), 0, 0);
                break;

            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }
	
	//设置进度条页数
	public void setPagesCount(int count) {
		mPageCount = count;
	}
	
	//分页的进度条的段值
	private int getProgressIsPageIndex(int progress, int max) {
		if (mPageCount < 2) {
			if (progress == 0) return 0;
			else return 1;
		}
		if (progress == 0) return 0;
		// 获取每一块的进度值
		int progressSizeEveryPage = getMax()/(mPageCount-1);
		for (int i = 1; i < mPageCount; i++) {
			if (progress <= (i)*progressSizeEveryPage && progress > ((i-1)*progressSizeEveryPage)) {
				if (progress > (2*i-1)*progressSizeEveryPage/2 ) return i;
				else return i-1;
			}
		}
		return mPageCount-1;
	}

	//外面调用上下按键翻页,需要同时滚动进度条效果
	public void setProgressSpecialPage(int pageIndex, int count) {
		if (count <= 1) {
			setProgress(0);
			return;
		}
		
		mPageCount = count;
		if (pageIndex < 0 || pageIndex >= mPageCount) return;

		int progressSizeEveryPage = getMax()/(mPageCount-1);
		
		setProgress( progressSizeEveryPage*pageIndex);
		//设置进度条按钮跟着移动
        onSizeChanged(getWidth(), getHeight(), 0, 0);
	}
}

还有怎么使用MainActivity

package com.vertical.pageseekbar;

import java.util.ArrayList;

import com.vertical.pageseekbar.R;
import com.vertical.view.VerticalPageSeekBar;
import com.vertical.view.VerticalPageSeekBar.OnSeekBarPageChangeListener;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity 
implements OnSeekBarPageChangeListener,OnClickListener{

	//页码进度条
	private VerticalPageSeekBar mPageSeekBar;
	//数据源
	private ArrayList<String> mArrayList;
	// 一页最多多少条数据
	protected int mMaxShowLinesPage = 20;
	// 当前是第几页
	protected int mCurrentSelectPageIndex = 0;
	// 当前有多少页
	protected int mPagesCount = 0;
	// 当前的有效记录数
	protected int mRecordCount = 0;
	// 存放每页数据第一条数据的索引
	protected ArrayList<Integer> mEveryPageOffestArray = new ArrayList<Integer>();
	// 当前页面的每一项的偏移数据 方便检索数据和删除数据
	protected ArrayList<Integer> mPageItemsIndex = new ArrayList<Integer>();
	//listview的适配器
	protected ListViewAdapter mAdapter;
	//测试数据的条数
	private int mnTestCount = 230;	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		initDatas();
		initView();
	}

	private void initDatas() {
		if (mArrayList == null) {
			mArrayList = new ArrayList<String>();
			for (int i = 0; i < mnTestCount; i++) {
				mArrayList.add("第   " + String.valueOf(i) + " 项");
			}
		}
	}

	private void initView() {
		mPageSeekBar = (VerticalPageSeekBar)findViewById(R.id.seekBar);
		mPageSeekBar.setSeekBarPageChangeListener(this);
		
		Button imageviewUp = (Button)findViewById(R.id.imageviewUp);
		imageviewUp.setOnClickListener(this);
		Button imageviewDown = (Button)findViewById(R.id.imageviewDown);
		imageviewDown.setOnClickListener(this);
	    ListView listView = (ListView)findViewById(R.id.listView1);
	    mAdapter = new ListViewAdapter(this);
	    listView.setAdapter(mAdapter);
	    
	    initResetListView(0);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.imageviewUp:
			setPrePage();
			break;
		case R.id.imageviewDown:
			setAftPage();
			break;
		default:
			break;
		}
	}

	//初始化进度条管理数据显示
	protected void initResetListView(int pageIndex) {
		mRecordCount = mArrayList.size();
		
		// 计算有多少页数据
	    mPagesCount = mRecordCount/mMaxShowLinesPage + (mRecordCount%mMaxShowLinesPage == 0 ? 0 : 1);
	    
	    // 判断 页面数目是2的时候, 简化为1页
	    if (mPagesCount == 2) {
	    	mMaxShowLinesPage = mMaxShowLinesPage * 2;
	    	mPagesCount = 1;
	    } else {
	    	mMaxShowLinesPage = 20;
	    }
		
		// 设置当前选中也为0
		mCurrentSelectPageIndex = pageIndex;
		if (mCurrentSelectPageIndex >= mPagesCount)
			mCurrentSelectPageIndex = mPagesCount - 1;
		//刷新每一页的首偏移
		setResetEveryPageOffestArray();
		//根据首偏移,得到这一页偏移序号
	    setResetPageItemsIndex(mCurrentSelectPageIndex);
		//上下按键翻页,需要同时滚动进度条效果.如果只有两页数据,不显示进度条
	    setSelectPageControl(mCurrentSelectPageIndex, mPagesCount,false);
		//总共几页,设置到进度条控件
	    mPageSeekBar.setPagesCount(mPagesCount);
	}
	
	//刷新每一页的首偏移
	protected void setResetEveryPageOffestArray() {
		int nValidItemNums = 0;
		mEveryPageOffestArray.clear();
		//记住每页的首偏移序号
		for (int i = 0; i < mPagesCount; i++) {
			int nRecordIndex = GetCountSpecialPage(i);
				mEveryPageOffestArray.add(nValidItemNums);
				nValidItemNums = nValidItemNums + nRecordIndex;
		}
		
		if (nValidItemNums != mRecordCount) {
			mRecordCount = nValidItemNums;
			// 计算有多少页数据
		    mPagesCount = mRecordCount/mMaxShowLinesPage + (mRecordCount%mMaxShowLinesPage == 0 ? 0 : 1);
		}
	}
	
	//根据首偏移,得到这一页偏移序号
	protected void setResetPageItemsIndex(int pageIndex) {
		if (pageIndex >= mEveryPageOffestArray.size()) return;
		int pageItemsCount = GetCountSpecialPage(pageIndex);
		int nRecordIndex = mEveryPageOffestArray.get(pageIndex).intValue();
		mPageItemsIndex.clear();
		//首偏移开始累加
		for(int i = nRecordIndex; i < pageItemsCount + nRecordIndex; i++) {
			mPageItemsIndex.add(i);
		}
		
		//刷新listview的适配器
		if (mAdapter != null) {
			mAdapter.notifyDataSetChanged();
		}
	}
	
	// 获取当前页面多少数据
	protected int GetCountSpecialPage(int nPage) {
		if (nPage < 0) return 0;
		if(nPage < (mPagesCount-1)) return mMaxShowLinesPage;
		//如果是最后一页,就是总的数据减去前面几页*每一页的数据
		//因为页码是从0开始,所以这里是最后一页
		if (nPage == mPagesCount - 1) return mRecordCount - mMaxShowLinesPage*(mPagesCount-1);
		return 0;
	}
	
	//上一页
	protected void setPrePage() {
		if (mCurrentSelectPageIndex == 0) return;
		mCurrentSelectPageIndex -= 1;
		//根据首偏移,得到这一页偏移序号
		setResetPageItemsIndex(mCurrentSelectPageIndex);
		// 翻页控件
		setSelectPageControl(mCurrentSelectPageIndex, mPagesCount,true);
	}
	
	//下一页
	protected void setAftPage() {
		if (mCurrentSelectPageIndex == (mPagesCount-1)) return;
		mCurrentSelectPageIndex += 1;
		//根据首偏移,得到这一页偏移序号
		setResetPageItemsIndex(mCurrentSelectPageIndex);
		// 翻页控件
		setSelectPageControl(mCurrentSelectPageIndex, mPagesCount,true);
	}
	
	//进度条滑动改变的数据,进行刷新
	protected void setPageChanged(int index, boolean isSetProgress) {
		if (index < 0 || index >= mPagesCount || mCurrentSelectPageIndex == index) return;
		mCurrentSelectPageIndex = index;
		
		// 刷新每一项的索引数据
		setResetPageItemsIndex(mCurrentSelectPageIndex);
		// 翻页控件
		setSelectPageControl(mCurrentSelectPageIndex, mPagesCount, isSetProgress);
	}

	//上下按键翻页,需要同时滚动进度条效果.如果只有两页数据,不显示进度条
	protected void setSelectPageControl(int index, int count, boolean isSet) {
		View selectPageBar = findViewById(R.id.layoutShow);
		if (selectPageBar != null) {
			//如果只有两页数据,不显示进度条
		if (count <= 1) selectPageBar.setVisibility(View.GONE);
		else selectPageBar.setVisibility(View.VISIBLE);
		//上下按键翻页,需要同时滚动进度条效果
		if (mPageSeekBar != null && isSet == true)
			mPageSeekBar.setProgressSpecialPage(mCurrentSelectPageIndex, mPagesCount);			
		}
	}
	
	//进度条滑动改变的数据,进行刷新
	@Override
	public void setSeekBarPageChanged(int page) {
		setPageChanged(page, false);
	}
	
	private class ViewHolder{
		TextView textView;
	}
	
	private class ListViewAdapter extends BaseAdapter{
		private Context mContext;
		private LayoutInflater mLayoutInflater;
		public ListViewAdapter(Context context) {
			mContext = context;
			mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}
		@Override
		public int getCount() {
			return mPageItemsIndex.size();
		}

		@Override
		public Object getItem(int position) {
			return 0;
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder vHolder = null;
			if (convertView == null) {
				vHolder = new ViewHolder();
				convertView = mLayoutInflater.inflate(R.layout.listview_item, null);
				vHolder.textView = (TextView)convertView.findViewById(R.id.textView1);
				convertView.setTag(vHolder);
			}else {
				vHolder = (ViewHolder) convertView.getTag();
			}
			vHolder.textView.setText(mArrayList.get(mPageItemsIndex.get(position).intValue()));
			return convertView;
		}
	}
	
}
到这里就结束了,有什么疑问,欢迎评论。。。

下载地址:http://download.csdn.net/detail/qq_16064871/9445535

android 打造变化多端的SeekBar(垂直和水平)

标签:

原文地址:http://blog.csdn.net/qq_16064871/article/details/50753777

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!