Android自定义控件----继承ViewGroup自定义ViewPager1(学习)

1效果图
这里写图片描述
2项目结构
这里写图片描述
3源码:
3.1自定义控件ImageViewGroup

package com.zhh.mybanner;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.orhanobut.logger.Logger;

/**
 * Created by 16838 on 2018/5/23.
 */
public class ImageViewGroup extends ViewGroup{
//  子视图的个数
    private int children;
//  子视图的宽度
    private int childwidth;
//  子视图的高度
    private int childheight;
//  此时的x值代表的是第一次按下位置的横坐标,每一次移动过程中 移动之前位置的横坐标
    private int myX;
//  每张图片的索引
    private int index=0;


    /**
     * 控件在xml文件中声明的时候必须要重写这个
     * @param context
     * @param attrs
     */
    public ImageViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 测量宽度和高度
     * 测量父布局的高度和宽度
     * 测量----布局----绘制
     * 绘制:针对绘制来说,因为我们是自定义的 ImageViewGroup容器,
     * 针对容器的绘制,其实就是容器内子控件的绘制过程,那么我们只需要
     * 调用系统自带的绘制,也就是说我们不需要重写该方法,调用系统自带的即可。
     *
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//      1求出子视图的个数
         children=getChildCount();
//      2求出子视图的宽度和高度
        if(children==0) {
//         如果子视图的个数是0,则设置ImageViewGroup的高度和宽度是0
           setMeasuredDimension(0,0);
        }else{
//          测量子视图的宽度和高度
            measureChildren(widthMeasureSpec,heightMeasureSpec);
//          拿到第一个子视图,绝对存在
            View view = getChildAt(0);
//      3根据子视图的宽度和高度,求出ImageViewGroup的宽度和高度
            childheight=view.getMeasuredHeight();
            childwidth = view.getMeasuredWidth();
            int width = childwidth*children;
//          设置ImageViewGroup的宽高
            setMeasuredDimension(width,childheight);

        }

    }

    /**
     * 参数 changed 表示ImageViewGroup位置发生改变时时true,不发生改变为false
     * 设置子布局的位置
     */
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if(changed) {
            int leftMargin=0;
            for(int  i= 0;  i< children; i++) {
//            当位置改变时设置每个子布局的位置
                View view=getChildAt(i);
//              设置子布局的位置
//                left 和 top 是控件左边缘和上边缘相对于父类控件左边缘和上边缘的距离。
//                right 和 bottom是空间右边缘和下边缘相对于父类控件左边缘和上边缘的距离。
//                所以下面这样计算
                view.layout(leftMargin,0,leftMargin+childwidth,childheight);
                leftMargin+=childwidth;
            }
        }

    }
    /**
     * 事件处理
     * 事件的传递过程中的调用方法:我们需要 调用 容器的拦截方法 onInterceptTouchEvent
     * 针对该方法我们可以理解为 如果说 该方法的返回值为true的时候,那么自定义的ImageViewGroup就会处理此次拦截事件
     * 如果说返回的值为false的时候,不会接受此次事件的处理过程,将会继续向下传递事件,我们希望ImageViewGroup处理接收事件,那么我们的
     * 返回值就是true,如果是true,真正处理该事件的方法是onTouchEvent
     *
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      switch (event.getAction()) {
//        按下一瞬间
          case  MotionEvent.ACTION_DOWN:
              Logger.t("111").d("ACTION_DOWN");
              myX= (int) event.getX();

              break;
//        移动过程
          case  MotionEvent.ACTION_MOVE:
//            距离父容器左边的距离,和x轴坐标相等
              int moveX = (int) event.getX();
              Logger.t("111").d("ACTION_MOVE+move"+moveX);
              int distance = moveX - myX;
//            scrollTo移动的是坐标,将整个父视图的左上角定为(0,0)
//            scrollBy移动的是距离
              scrollBy(-distance, 0);
              myX=moveX;
              break;
//        抬起一瞬间
          case  MotionEvent.ACTION_UP:
              Logger.t("111").d("ACTION_UP");
//             移动的位移,原点减视图左上角坐标   0-左上角坐标
               int scrollX =  getScrollX();
//              计算索引
               index = (scrollX+childwidth/2)/childwidth;
               if(index<0) {
                   //说明此时已经滑到左边第一张图片
                   index=0;
               }else if(index>children-1) {
                   //说明此时已经滑动到最后一张图片
                   index=children-1;
               }
//            scrollTo移动的是坐标,将整个父视图的左上角定为(0,0)
//            scrollBy移动的是距离
              scrollTo(index * childwidth,0);

               break;
          default:
              break;

      }
        return true;
    }


}

3.2MainActivity的activity_main.xml中引用

<LinearLayout 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">

    <com.zhh.mybanner.ImageViewGroup
        android:id="@+id/imageViewGroup"
        android:layout_width="match_parent"
        android:layout_height="200dp"

        >

    </com.zhh.mybanner.ImageViewGroup>

</LinearLayout>

3.3MainActivity中放入图片数据

package com.zhh.mybanner;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {
    private ImageViewGroup imageViewGroup;

    int []images={R.drawable.a1,R.drawable.a2,R.drawable.a3};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageViewGroup = findViewById(R.id.imageViewGroup);
//      拿到手机屏幕的宽度
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
//     把图片放到imageViewGroup中
        for(int i = 0; i <images.length ; i++) {
            ImageView iv =new ImageView(this);
            iv.setScaleType(ImageView.ScaleType.FIT_XY);
//          设置的宽度是屏幕宽度,高度包裹
            iv.setLayoutParams(new ViewGroup.LayoutParams(width, ViewGroup.LayoutParams.WRAP_CONTENT));
            iv.setImageResource(images[i]);
            imageViewGroup.addView(iv);

        }
    }


}

参考视频:
https://www.imooc.com/learn/793
源码下载MyCheckBox—-mybanner
https://download.csdn.net/download/zhaihaohao1/10434975

猜你喜欢

转载自blog.csdn.net/zhaihaohao1/article/details/80434499