前言
????在Android開發(fā)中,系統(tǒng)控件已經(jīng)遠(yuǎn)遠(yuǎn)不能滿足我們?nèi)粘P枨?,可以使用以下方式?shí)現(xiàn)控件的自定義:
1.系統(tǒng)控件的重新組合
2.自定義類繼承View
3.自定義類繼承ViewGroup

效果演示:

源碼:
MyViewPager:
public class MyViewPagerextends ViewGroup {
private MyScrollerscroller;
? ? /**
* 手勢(shì)識(shí)別器
* 1.定義出來
* 2.實(shí)例化-把想要的方法給重寫
* 3.在onTouchEvent()把事件傳遞給手勢(shì)識(shí)別器
*/
? ? private GestureDetectordetector;
? ? /**
* 當(dāng)前頁(yè)面的下標(biāo)位置
*/
? ? private int currentIndex;
? ? private float startX;
? ? public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
? ? ? ? //實(shí)例化
? ? ? ? initView(context);
? ? }
private void initView(final Context context) {
scroller=new MyScroller();
? ? ? ? //2.實(shí)例化手勢(shì)識(shí)別器
? ? ? ? detector =new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
? ? ? ? ? ? public void onLongPress(MotionEvent e) {
super.onLongPress(e);
? ? ? ? ? ? ? ? Toast.makeText(context, "長(zhǎng)按", Toast.LENGTH_SHORT).show();
? ? ? ? ? ? }
/**
? ? ? ? ? ? * @param e1
? ? ? ? ? ? * @param e2
? ? ? ? ? ? * @param distanceX 在X軸滑動(dòng)了的距離
? ? ? ? ? ? * @param distanceY 在Y軸滑動(dòng)了的距離
? ? ? ? ? ? * @return
? ? ? ? ? ? */
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
/**
*x:要在X軸移動(dòng)的距離
*y:要在Y軸移動(dòng)的距離
*/
? ? ? ? ? ? ? ? scrollBy((int) distanceX, 0);
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
@Override
? ? ? ? ? ? public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(context, "雙擊", Toast.LENGTH_SHORT).show();
? ? ? ? ? ? ? ? return super.onDoubleTap(e);
? ? ? ? ? ? }
});
? ? }
@Override
? ? protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i =0; i < getChildCount(); i++) {
View childView = getChildAt(i);
? ? ? ? ? ? childView.layout(i * getWidth(), 0, (i +1) * getWidth(), getHeight());
? ? ? ? }
}
@Override
? ? public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
? ? ? ? //3.把事件傳遞給手勢(shì)識(shí)別器
? ? ? ? detector.onTouchEvent(event);
? ? ? ? switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//1.記錄坐標(biāo)
? ? ? ? ? ? ? ? startX = event.getX();
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_MOVE:
break;
? ? ? ? ? ? case MotionEvent.ACTION_UP:
//2.來到新的坐標(biāo)
? ? ? ? ? ? ? ? float endX = event.getX();
? ? ? ? ? ? ? ? //下標(biāo)位置
? ? ? ? ? ? ? ? int tempIndex =currentIndex;
? ? ? ? ? ? ? ? if ((startX - endX) > getWidth() /2) {
//顯示下一個(gè)頁(yè)面
? ? ? ? ? ? ? ? ? ? tempIndex++;
? ? ? ? ? ? ? ? }else if ((endX -startX) > getWidth() /2) {
//顯示上一個(gè)頁(yè)面
? ? ? ? ? ? ? ? ? ? tempIndex--;
? ? ? ? ? ? ? ? }
//根據(jù)下標(biāo)位置移動(dòng)到指定的頁(yè)面
? ? ? ? ? ? ? ? scrollToPager(tempIndex);
? ? ? ? ? ? ? ? break;
? ? ? ? }
return true;
? ? }
/**
* 屏蔽非法值,根據(jù)位置移動(dòng)到指定頁(yè)面
*
? ? * @param tempIndex
? ? */
? ? private void scrollToPager(int tempIndex) {
if (tempIndex <0) {
tempIndex =0;
? ? ? ? }
if (tempIndex > getChildCount() -1) {
tempIndex = getChildCount() -1;
? ? ? ? }
//當(dāng)前頁(yè)面的下標(biāo)位置
? ? ? ? currentIndex=tempIndex;
? ? ? ? int distanceX=currentIndex*getWidth()-getScrollX();
? ? ? ? //scrollTo(currentIndex*getWidth(),0);
? ? ? ? scroller.startScroll(getScrollX(),getScrollY(), distanceX,0);
? ? ? ? invalidate();? //onDraw() 和 computeScroll()都會(huì)執(zhí)行
? ? }
@Override
? ? public void computeScroll() {
if(scroller.cuputeScrollOffset()){
float currX =scroller.getCurrX();
? ? ? ? ? ? scrollTo((int) currX,0);
? ? ? ? ? ? invalidate();
? ? ? ? }
}
}
MyScroller:
public class MyScroller {
? ? private float startX;
? ? private float startY;
? ? private int distanceX;
? ? private int distanceY;
? ? private long startTime;
? ? private long totalTime =500;
? ? private boolean isFinish;
? ? private float currX;
? ? public float getCurrX() {
return currX;
? ? }
public void startScroll(float startX, float startY, int distanceX, int distanceY) {
this.startX=startX;
? ? ? ? this.startY=startY;
? ? ? ? this.distanceX=distanceX;
? ? ? ? this.distanceY=distanceY;
? ? ? ? this.startTime= SystemClock.uptimeMillis(); //系統(tǒng)開機(jī)時(shí)間
? ? ? ? this.isFinish=false;
? ? }
? ? public boolean cuputeScrollOffset(){
if(isFinish){
return? false;
? ? ? ? }
long endTime = SystemClock.uptimeMillis();
? ? ? ? //這一小段所花的時(shí)間
? ? ? ? long passTime = endTime -startTime;
? ? ? ? if(passTime
//還沒有移動(dòng)結(jié)束
//計(jì)算平均速度
//? ? ? ? ? ? float voleCity = distanceX/totalTime;
//移動(dòng)這個(gè)一小段對(duì)應(yīng)的距離
? ? ? ? ? ? float distanceSamllX = passTime*distanceX/totalTime;
? ? ? ? ? ? currX =startX + distanceSamllX;
? ? ? ? }else{
//移動(dòng)結(jié)束
? ? ? ? ? ? isFinish =true;
? ? ? ? ? ? currX =startX +distanceX;
? ? ? ? }
return? true;
? ? }
}
MainActivity:
public class MainActivityextends Activity {
private MyViewPagermyViewPager;
? ? private int[]ids = {R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6};
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? myViewPager = findViewById(R.id.my_viewpager);
? ? ? ? //添加頁(yè)面
? ? ? ? for (int i =0; i
ImageView imageView =new ImageView(this);
? ? ? ? ? ? imageView.setBackgroundResource(ids[i]);
? ? ? ? ? // imageView.setScaleType(ImageView.ScaleType.FIT_XY);
//添加到MyViewPager這個(gè)View中
? ? ? ? ? ? myViewPager.addView(imageView);
? ? ? ? }
}
}
XML文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? tools:context=".MainActivity">
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="match_parent"
? ? ? ? android:id="@+id/my_viewpager"
? ? ? ? />
</android.support.v7.widget.LinearLayoutCompat>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 初次寫文章
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?有什么不足望指點(diǎn),謝謝