欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义View实现阶梯梯形布局以及二维码的实现

程序员文章站 2022-03-20 11:41:21
...

一.要求

实现如图所示效果,标题栏通过组合View的方式进行实现,统一对外暴露左侧按钮和右侧按钮点击的方法,在点击右侧的回调方法中跳转到图二所示页面,图二的页面标题栏显示上一个页面组合View的视图,通过自定义ViewGroup的方式实现梯形布局(下一个视图的起始位置是上一个视图的结束位置)。图一中间的进度条使用继承自View的方式进行实现,并使用自定义属性的方式来设置进度条中间的颜色。点击扫描二维码按钮之后,进度条开始以每秒10%的进度进行,当进度条走到100%后,跳转到图三的扫描二维码页面,实现扫描二维码的功能

自定义View实现阶梯梯形布局以及二维码的实现


自定义View实现阶梯梯形布局以及二维码的实现

二.代码实现

 1.标题栏

  

package com.example.zhouyf.zhoukao1;

import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * Created by Zhouyf on 2017/11/4.
 */

public class TitleViewActivity extends LinearLayout {
//    private OnAddDelClickListener listener;
    private ImageView img_left;
    private ImageView img_right;

    //
//    interface OnAddDelClickListener {
//        void onBackView(View v);
//        void onGroupView(View v);
//    }
//    public void setOnAddDelClickListener(OnAddDelClickListener listener){
//        if (listener!=null){
//            this.listener = listener;
//        }
//    }
    public TitleViewActivity(Context context) {
        this(context,null);
    }

    public TitleViewActivity(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public TitleViewActivity(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs, defStyleAttr);
    }

    private void initView(Context context, AttributeSet attrs, int defStyleAttr) {
        View v = inflate(context, R.layout.title, this);
        img_left = (ImageView) v.findViewById(R.id.title_back);
        img_right = (ImageView) v.findViewById(R.id.title_right);
        TextView txt_title = (TextView) v.findViewById(R.id.title_center);
//        img_left.setOnClickListener(new OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                listener.onBackView(v);
//            }
//        });

    }
    public void setLeftClick(OnClickListener lister){
        img_left.setOnClickListener(lister) ;
    }
    public void setRightClick(OnClickListener lister){
        img_right.setOnClickListener(lister);
    }

}
 2.mainactivity

package com.example.zhouyf.zhoukao1;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity{
    private final int UPDATE_PROGRESS = 001;
    private static final int FLAG = 0x123;
    Handler myHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
//            switch (msg.what){
//                case 001:
//                    int progress =(int) msg.obj;
//                    pb.setProgress(progress);
//                    if (progress==100){
//                        Intent intent = new Intent(MainActivity.this,ZxingActivity.class);
//                        startActivity(intent);
//                        progress=0;
//                    }
//                    break;
//            }
            switch (msg.what) {
                case FLAG:
                    int progress = pb.getProgress();
                    progress += 10;
                    if (progress > 100) {
                        progress = 0;
                        Intent intent = new Intent(MainActivity.this,ZxingActivity.class);
                        startActivity(intent);
                    }
                    pb.setProgress(progress);
                    myHandler.sendEmptyMessageDelayed(FLAG, 1000);
                    break;
            }
        }
    };
    private RoundProgressBar pb;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TitleViewActivity tva = (TitleViewActivity) findViewById(R.id.title);
        pb = (RoundProgressBar) findViewById(R.id.roundProgressBar2);
        Button btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(){
                    public void run(){
//                        for (int i=0;i<100;i++){
//                            Message msg = myHandler.obtainMessage();
//                            msg.what = UPDATE_PROGRESS;
//                            msg.obj = i+10;
//                            myHandler.sendMessage(msg);
//                            try {
//                                Thread.sleep(100);//休眠100ms
//                            } catch (InterruptedException e) {
//                                e.printStackTrace();
//                            }
//                        }
                        myHandler.sendEmptyMessageDelayed(FLAG, 1000);
                    }
                }.start();
            }
        });
        tva.setLeftClick(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        tva.setRightClick(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,GroupActivity.class);
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onStop() {
        super.onStop();
        myHandler.removeMessages(FLAG);
    }
}
3.阶梯布局的主activity

package com.example.zhouyf.zhoukao1;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class GroupActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_view_group);
        TitleViewActivity group_tva = (TitleViewActivity) findViewById(R.id.g_title);

        group_tva.setLeftClick(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}
4.继承view的阶梯布局activity

package com.example.zhouyf.zhoukao1;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Zhouyf on 2017/11/4.
 */

public class MyViewGroup extends ViewGroup {
    public MyViewGroup(Context context) {
        super(context);
    }

    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec,heightMeasureSpec);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        int startWidth = 0;
        int startHeight = 0;
        for (int i=0; i<count; i++){
            View v = getChildAt(i);
            v.layout(startWidth,startHeight,startWidth+v.getMeasuredWidth(),startHeight+v.getMeasuredHeight());
            startWidth += v.getMeasuredWidth();
            startHeight += v.getMeasuredHeight();
        }
    }
}
5.二维码设置类

package com.example.zhouyf.zhoukao1;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;
import com.google.zxing.client.android.camera.CameraManager;


/**
 * Created by Zhouyf on 2017/11/4.
 */

public class AutoScannerView extends View {
    private static final String TAG = AutoScannerView.class.getSimpleName();
    private Paint maskPaint;
    private Paint linePaint;
    private Paint traAnglePaint;
    private Paint textPaint;
    private CameraManager cameraManager;

    private final int maskColor = Color.parseColor("#60000000");                          //蒙在摄像头上面区域的半透明颜色
    private final int triAngleColor = Color.parseColor("#76EE00");                        //边角的颜色
    private final int lineColor = Color.parseColor("#FF0000");                            //中间线的颜色
    private final int textColor = Color.parseColor("#CCCCCC");                            //文字的颜色
    private final int triAngleLength = dp2px(20);                                         //每个角的点距离
    private final int triAngleWidth = dp2px(4);                                           //每个角的点宽度
    private final int textMarinTop = dp2px(30);                                           //文字距离识别框的距离
    private int lineOffsetCount = 0;

    public AutoScannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        maskPaint.setColor(maskColor);

        traAnglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        traAnglePaint.setColor(triAngleColor);
        traAnglePaint.setStrokeWidth(triAngleWidth);
        traAnglePaint.setStyle(Paint.Style.STROKE);

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setColor(lineColor);

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(textColor);
        textPaint.setTextSize(dp2px(14));
    }


    public void setCameraManager(CameraManager cameraManager) {
        this.cameraManager = cameraManager;
        invalidate();//重新进入可能不刷新,所以调用一次。
    }
    @Override
    protected void onDraw(Canvas canvas) {
        if (cameraManager == null)
            return;
        Rect frame = cameraManager.getFramingRect();
        Rect previewFrame = cameraManager.getFramingRectInPreview();
        if (frame == null || previewFrame == null) {
            return;
        }

        int width = canvas.getWidth();
        int height = canvas.getHeight();

        // 除了中间的识别区域,其他区域都将蒙上一层半透明的图层
        canvas.drawRect(0, 0, width, frame.top, maskPaint);
        canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, maskPaint);
        canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, maskPaint);
        canvas.drawRect(0, frame.bottom + 1, width, height, maskPaint);

        String text = "将二维码放入框内,即可自动扫描";
        canvas.drawText(text, (width - textPaint.measureText(text)) / 2, frame.bottom + textMarinTop, textPaint);

        // 四个角落的三角
        Path leftTopPath = new Path();
        leftTopPath.moveTo(frame.left + triAngleLength, frame.top + triAngleWidth / 2);
        leftTopPath.lineTo(frame.left + triAngleWidth / 2, frame.top + triAngleWidth / 2);
        leftTopPath.lineTo(frame.left + triAngleWidth / 2, frame.top + triAngleLength);
        canvas.drawPath(leftTopPath, traAnglePaint);

        Path rightTopPath = new Path();
        rightTopPath.moveTo(frame.right - triAngleLength, frame.top + triAngleWidth / 2);
        rightTopPath.lineTo(frame.right - triAngleWidth / 2, frame.top + triAngleWidth / 2);
        rightTopPath.lineTo(frame.right - triAngleWidth / 2, frame.top + triAngleLength);
        canvas.drawPath(rightTopPath, traAnglePaint);

        Path leftBottomPath = new Path();
        leftBottomPath.moveTo(frame.left + triAngleWidth / 2, frame.bottom - triAngleLength);
        leftBottomPath.lineTo(frame.left + triAngleWidth / 2, frame.bottom - triAngleWidth / 2);
        leftBottomPath.lineTo(frame.left + triAngleLength, frame.bottom - triAngleWidth / 2);
        canvas.drawPath(leftBottomPath, traAnglePaint);

        Path rightBottomPath = new Path();
        rightBottomPath.moveTo(frame.right - triAngleLength, frame.bottom - triAngleWidth / 2);
        rightBottomPath.lineTo(frame.right - triAngleWidth / 2, frame.bottom - triAngleWidth / 2);
        rightBottomPath.lineTo(frame.right - triAngleWidth / 2, frame.bottom - triAngleLength);
        canvas.drawPath(rightBottomPath, traAnglePaint);

        //循环划线,从上到下
        if (lineOffsetCount > frame.bottom - frame.top - dp2px(10)) {
            lineOffsetCount = 0;
        } else {
            lineOffsetCount = lineOffsetCount + 6;
//            canvas.drawLine(frame.left, frame.top + lineOffsetCount, frame.right, frame.top + lineOffsetCount, linePaint);    //画一条红色的线
            Rect lineRect = new Rect();
            lineRect.left = frame.left;
            lineRect.top = frame.top + lineOffsetCount;
            lineRect.right = frame.right;
            lineRect.bottom = frame.top + dp2px(10) + lineOffsetCount;
            canvas.drawBitmap(((BitmapDrawable)(getResources().getDrawable(R.drawable.scanline))).getBitmap(), null, lineRect, linePaint);
        }
        postInvalidateDelayed(10L, frame.left, frame.top, frame.right, frame.bottom);
    }

    private int dp2px(int dp) {
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * density + 0.5f);
    }

}

6.二维码的主activity

package com.example.zhouyf.zhoukao1;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.SurfaceView;
import android.widget.Toast;

import com.google.zxing.Result;
import com.google.zxing.client.android.BaseCaptureActivity;

public class ZxingActivity extends BaseCaptureActivity {
    private static final String TAG = ZxingActivity.class.getSimpleName();
    private SurfaceView surfaceView;
    private AutoScannerView autoScannerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zxing);
        surfaceView = (SurfaceView) findViewById(R.id.preview_view);
        autoScannerView = (AutoScannerView) findViewById(R.id.autoscanner_view);
    }
    @Override
    protected void onResume() {
        super.onResume();
        autoScannerView.setCameraManager(cameraManager);
    }

    @Override
    public SurfaceView getSurfaceView() {
        return (surfaceView == null) ? (SurfaceView) findViewById(R.id.preview_view) : surfaceView;
    }

    @Override
    public void dealDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
        playBeepSoundAndVibrate(true, false);
        Toast.makeText(this, rawResult.getText(), Toast.LENGTH_LONG).show();
//        对此次扫描结果不满意可以调用
//        reScan();
    }
}

7.圆形进度条

package com.example.zhouyf.zhoukao1;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Zhouyf on 2017/11/4.
 */

public class RoundProgressBar extends View {
    /**
     * 画笔对象的引用
     */
    private Paint paint;

    /**
     * 圆环的颜色
     */
    private int roundColor;

    /**
     * 圆环进度的颜色
     */
    private int roundProgressColor;

    /**
     * 中间进度百分比的字符串的颜色
     */
    private int textColor;

    /**
     * 中间进度百分比的字符串的字体
     */
    private float textSize;

    /**
     * 圆环的宽度
     */
    private float roundWidth;

    /**
     * 最大进度
     */
    private int max;

    /**
     * 当前进度
     */
    private int progress;
    /**
     * 是否显示中间的进度
     */
    private boolean textIsDisplayable;

    /**
     * 进度的风格,实心或者空心
     */
    private int style;

    public static final int STROKE = 0;
    public static final int FILL = 1;
    public RoundProgressBar(Context context) {
        this(context, null);
    }

    public RoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context,attrs,defStyle);
        paint = new Paint();
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);
        //获取自定义属性和默认值
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);
        max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
        style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);
        mTypedArray.recycle();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 画最外层的大圆环
         */
        int centre = getWidth()/2; //获取圆心的x坐标
        int radius = (int) (centre - roundWidth/2); //圆环的半径
        paint.setColor(roundColor); //设置圆环的颜色
        paint.setStyle(Paint.Style.STROKE); //设置空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setAntiAlias(true);  //消除锯齿
        canvas.drawCircle(centre, centre, radius, paint); //画出圆环
        /**
         * 画进度百分比
         */
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
        int percent = (int)(((float)progress / (float)max) * 100);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0
        float textWidth = paint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间

        if(textIsDisplayable && percent != 0 && style == STROKE){
            canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize/2, paint); //画出进度百分比
        }

        /**
         * 画圆弧 ,画圆环的进度
         */
        //设置进度是实心还是空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setColor(roundProgressColor);  //设置进度的颜色
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius);  //用于定义的圆弧的形状和大小的界限
        switch (style) {
            case STROKE:{
                paint.setStyle(Paint.Style.STROKE);
                canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //根据进度画圆弧
                break;
            }
            case FILL:{
                paint.setStyle(Paint.Style.FILL_AND_STROKE);
                if(progress !=0)
                    canvas.drawArc(oval, 0, 360 * progress / max, true, paint);  //根据进度画圆弧
                break;
            }
        }
    }

    public synchronized int getMax() {
        return max;
    }
    /**
     * 设置进度的最大值
     * @param max
     */
    public synchronized void setMax(int max) {
        if(max < 0){
            throw new IllegalArgumentException("max not less than 0");
        }
        this.max = max;
    }

    /**
     * 获取进度.需要同步
     * @return
     */
    public synchronized int getProgress() {
        return progress;
    }

    /**
     * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
     * 刷新界面调用postInvalidate()能在非UI线程刷新
     * @param progress
     */
    public synchronized void setProgress(int progress) {
        if(progress < 0){
            throw new IllegalArgumentException("progress not less than 0");
        }
        if(progress > max){
            progress = max;
        }
        if(progress <= max){
            this.progress = progress;
            postInvalidate();
        }

    }


    public int getCricleColor() {
        return roundColor;
    }

    public void setCricleColor(int cricleColor) {
        this.roundColor = cricleColor;
    }

    public int getCricleProgressColor() {
        return roundProgressColor;
    }

    public void setCricleProgressColor(int cricleProgressColor) {
        this.roundProgressColor = cricleProgressColor;
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public float getRoundWidth() {
        return roundWidth;
    }

    public void setRoundWidth(float roundWidth) {
        this.roundWidth = roundWidth;
    }
}


布局文件

1.mainactivity对应的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android_custom="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.zhouyf.zhoukao1.MainActivity">
    <!--标题设置-->
    <com.example.zhouyf.zhoukao1.TitleViewActivity
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/title"
        >

    </com.example.zhouyf.zhoukao1.TitleViewActivity>

    <!--圆形进度条-->
    <com.example.zhouyf.zhoukao1.RoundProgressBar
        android:id="@+id/roundProgressBar2"
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:layout_centerInParent="true"
        android_custom:roundColor="#D1D1D1"
        android_custom:roundProgressColor="#00fe00"
        android_custom:textColor="#888888"
        android_custom:textIsDisplayable="true"
        android_custom:roundWidth="10dip"
        android_custom:textSize="18sp" >

    </com.example.zhouyf.zhoukao1.RoundProgressBar>
    <Button
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:text="扫描二维码"
        android:gravity="center"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:textSize="20dp"
        android:background="#619f68"
        android:textColor="#9f4258"
        android:layout_below="@+id/roundProgressBar2"
        android:id="@+id/btn"/>
</RelativeLayout>


2.二维码对应的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.zhouyf.zhoukao1.ZxingActivity">
    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <com.example.zhouyf.zhoukao1.AutoScannerView
        android:id="@+id/autoscanner_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

3.标题布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="#d4dbed"
    android:padding="5dp">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:src="@drawable/left"
        android:layout_weight="1"
        android:id="@+id/title_back"
        />
    <TextView
        android:layout_width="500dp"
        android:layout_height="wrap_content"
        android:text="那些花儿"
        android:textSize="26dp"
        android:gravity="center"
        android:layout_weight="1"
        android:id="@+id/title_center"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:src="@drawable/shenfen"
        android:layout_weight="1"
        android:id="@+id/title_right"/>

</LinearLayout>
4.阶梯布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.zhouyf.zhoukao1.GroupActivity">
    <com.example.zhouyf.zhoukao1.TitleViewActivity
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/g_title">
    </com.example.zhouyf.zhoukao1.TitleViewActivity>
    <com.example.zhouyf.zhoukao1.MyViewGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="127dp"
            android:layout_height="50dp"
            android:background="#619ea0" />
        <TextView
            android:layout_width="127dp"
            android:layout_height="50dp"
            android:background="#7561a0"/>
        <TextView
            android:layout_width="127dp"
            android:layout_height="50dp"
            android:background="#9fa061" />
    </com.example.zhouyf.zhoukao1.MyViewGroup>
</LinearLayout>

实现二维码时需要

1.通过new import moudle引入 zxinglite这个文件夹

2.需要在项目清单文件中设置

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />