说明:实现二维码扫描:先在Android Studio上导入libzing的Module,然后在当前app的Dependencies上把那个libzing库文件添加上去,这样我们的app就关联了那个libzing库。
详情参考: http://blog.csdn.net/weixin_39586678/article/details/78132046#comments
需求:
(1)标题栏通过组合View的方式进行实现,统一对外暴露左侧按钮和右侧按钮点击的方法;
(2)在点击右侧的回调方法中跳转到图二所示页面,图二的页面标题栏显示上一个页面组合View的视图,通过自定义ViewGroup的方式实现梯形布局(下一个视图的起始位置是上一个视图的结束位置)。
(3)图一中间的进度条使用继承自View的方式进行实现,并使用自定义属性的方式来设置进度条中间的颜色。
(4)点击扫描二维码按钮之后,进度条开始以每秒10%的进度进行,当进度条走到100%后,跳转到图三的扫描二维码页面,实现扫描二维码的功能
效果图:
图一:
图二:
图三:
功能代码:
1. 先定义自定义组合控件的标题栏 title_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!--首先定义标题栏,使用组合控件--> <LinearLayout android:layout_height="52dp" android:background="#d3daec" android:orientation="horizontal" android:layout_width="match_parent" android:layout_gravity="center_vertical"> <Button android:id="@+id/button_backward" android:layout_width="70dp" android:layout_height="match_parent" android:drawableLeft="@drawable/back_arrow" android:drawablePadding="6dp" android:background="#d3daec" android:gravity="center" android:paddingLeft="5dp" android:singleLine="true" /> <TextView android:text="那些花儿" android:textSize="28sp" android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:textColor="#878787" android:layout_gravity="center" android:layout_height="wrap_content" /> <Button android:singleLine="true" android:background="#d3daec" android:layout_width="70dp" android:id="@+id/button_forward" android:layout_marginRight="15dp" android:layout_height="wrap_content" android:drawableRight="@mipmap/ic_launcher" /> </LinearLayout> </LinearLayout>
对应的实现自定义组合控件的标题栏的java类:TitleView.java
package com.bwie.weekone_moni_jiekou.view; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import com.bwie.weekone_moni_jiekou.R; /** * 自定义组合控件实现标题栏 */ public class TitleView extends LinearLayout implements View.OnClickListener{ private Context conText; public TitleView(Context context) { super(context); } public TitleView(Context context, AttributeSet attrs) { super(context, attrs); conText = context; //将自定义组合控件布局按钮id填充到当前页面 View view = LayoutInflater.from(context).inflate(R.layout.title_layout, this, true); Button button_backward = view.findViewById(R.id.button_backward); Button button_forward = view.findViewById(R.id.button_forward); button_forward.setOnClickListener(this); button_backward.setOnClickListener(this); } public TitleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void onClick(View view) { //调用接口的方法 titleViewClickListener.titleViewButtonClicked(view); } //自定义 接口的成员 OnTitleViewClickListener titleViewClickListener; //自定义 实现按钮点击事件的接口 public interface OnTitleViewClickListener{ public void titleViewButtonClicked(View view); //View view:传的参数 } //使用setter设置接口回调的声明变量 public void setOnTitleViewClickListener(OnTitleViewClickListener titleViewClickListener){ //在setter中把这个接口的实现 赋值给这个TitleView类上面实现的接口 this.titleViewClickListener = titleViewClickListener; } }
2. 实现引用标题栏的主代码类:MainActivity.java
package com.bwie.weekone_moni_jiekou; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; import com.bwie.weekone_moni_jiekou.view.CustomCircleView; import com.bwie.weekone_moni_jiekou.view.TitleView; public class MainActivity extends AppCompatActivity { private CustomCircleView custom_circle; private TitleView titleView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //拿到圆形滚动条和自定义标题栏的视图 custom_circle = (CustomCircleView) findViewById(R.id.custom_Circle); titleView = (TitleView) findViewById(R.id.titleView); //调用自定义控件类中接口,实现按钮的点击事件 titleView.setOnTitleViewClickListener(new TitleView.OnTitleViewClickListener() { @Override public void titleViewButtonClicked(View view) { //判断当前点击的view是哪个按钮 if (view.getId() == R.id.button_backward){ //左边的返回按钮 Toast.makeText(MainActivity.this, "点击返回", Toast.LENGTH_SHORT).show(); finish(); }else if (view.getId() == R.id.button_forward){ //右边的登录按钮{ //点击右边的按钮 跳转到 SecondActivity,显示矩形view Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); finish(); } } }); } //点击按钮,调用滚动条的方法,扫描二维码 public void saoMiaoCode(View view) { custom_circle.start(); } }
实现主代码类布局的xml文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <!--调用自定义组合控件的标题栏--> <com.bwie.weekone_moni_jiekou.view.TitleView android:layout_weight="1" android:id="@+id/titleView" android:layout_height="0dp" android:layout_width="match_parent" ></com.bwie.weekone_moni_jiekou.view.TitleView> <LinearLayout android:gravity="center" android:layout_weight="6" android:layout_height="0dp" android:orientation="vertical" android:layout_width="match_parent" > <com.bwie.weekone_moni_jiekou.view.CustomCircleView android:id="@+id/custom_Circle" android:layout_width="300dp" android:layout_height="300dp" /> <Button android:textSize="21sp" android:text="扫描二维码" android:textColor="#80706e" android:layout_width="188dp" android:background="#619e85" android:onClick="saoMiaoCode" android:layout_marginTop="58dp" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>
3. 跳转后的页面,显示矩形view:SecondActivity.java
package com.bwie.weekone_moni_jiekou; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; //显示矩形view的页面 public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); //点击第二个页面的返回按钮跳转至上一个页面 Button button_backward = (Button) findViewById(R.id.button_backward); button_backward.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(SecondActivity.this, MainActivity.class); startActivity(intent); finish(); } }); } }
对应的xml布局:activity_second.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <!--首先定义标题栏,使用组合控件--> <LinearLayout android:layout_weight="0.35" android:layout_height="0dp" android:background="#d3daec" android:orientation="horizontal" android:layout_width="match_parent" android:layout_gravity="center_vertical"> <Button android:id="@+id/button_backward" android:layout_width="70dp" android:layout_height="match_parent" android:drawableLeft="@drawable/back_arrow" android:drawablePadding="6dp" android:background="#d3daec" android:gravity="center" android:paddingLeft="5dp" android:singleLine="true" /> <TextView android:text="那些花儿" android:textSize="28sp" android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:textColor="#878787" android:layout_gravity="center" android:layout_height="wrap_content" /> <Button android:singleLine="true" android:layout_width="70dp" android:layout_marginRight="15dp" android:layout_height="wrap_content" android:drawableRight="@mipmap/ic_launcher" /> </LinearLayout> <com.bwie.weekone_moni_jiekou.view.CustomRectView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="6"></com.bwie.weekone_moni_jiekou.view.CustomRectView> </LinearLayout>
4. 实现自定义圆环进度条view:CustomCircleView.java
package com.bwie.weekone_moni_jiekou.view; import android.content.Context; import android.content.Intent; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import com.xys.libzxing.zxing.activity.CaptureActivity; /** * 自定义圆环进度条,显示进度百分比 * 点击扫描二维码按钮之后,进度条开始以每秒10%的进度进行, * 当进度条走到100%后,跳转到图三的扫描二维码页面,实现扫描二维码的功能 */ public class CustomCircleView extends View{ private int progress = 0; private Context context; private Paint paint; public CustomCircleView(Context context) { super(context); } public CustomCircleView(Context context, AttributeSet attrs) { this(context, attrs,0); } public CustomCircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; //创建一支画笔 paint = new Paint(); //设置画笔的颜色 paint.setColor(Color.BLUE); //设置画笔的style:内容是填充的空心圆 paint.setStyle(Paint.Style.STROKE); } //执行进度条是耗时操作,需放在子线程中执行,进度达到100%后跳转至 扫描二维码 页面 public void start() { new Thread(new Runnable() { @Override public void run() { while (true) { if (progress >= 360) { Intent intent = new Intent(context, CaptureActivity.class); context.startActivity(intent); return; } progress += 10; //子线程刷新 系统调用onDraw() 方法 postInvalidate(); try { Thread.sleep(188); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //(1)获取当前自定义view的宽高度 int x = getWidth() / 2; int y = getHeight() / 2; //(2)设置圆半径的大小 int radius = 200; //(3)设置画笔的粗细 paint.setStrokeWidth(16); //(4)定义一个矩形区域:RectF对象持有一个矩形的四个float坐标值 RectF rectF = new RectF(x- radius,y - radius,x + radius, y + radius); //画一个圆弧:drawArc方法:绘制圆弧,该方法用于在画布上绘制圆弧,通过指定圆弧所在的椭圆对象、起始角度、终止角度来实现。 canvas.drawArc(rectF,-90,progress,false,paint); //(5)把progress转换为int值 int intProgress = (int) ((float) progress / 360 * 100); //(6) measureText 测量字符串的宽度 float textWidth = paint.measureText(intProgress + "%"); //(7)定义一个矩形区域:Rect对象持有一个矩形的四个integer坐标值 Rect rect = new Rect(); //测量矩形中百分比的值的位置 paint.getTextBounds(intProgress+"%",0,(intProgress+"%").length(),rect); //(8)设置画笔写出内容的size高度和粗细 paint.setTextSize(28); paint.setStrokeWidth(1); //(9)画出文字 rect.height() 获取字符串的高度 canvas.drawText(intProgress+"%",x-textWidth/2,y+textWidth/2,paint); } }
5. 实现自定义矩形view的类:CustomRectView.java
package com.bwie.weekone_moni_jiekou.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; /** * 自定义3个首尾相连的矩形view */ public class CustomRectView extends View{ public CustomRectView(Context context) { super(context); } public CustomRectView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomRectView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //(1)设置画笔的size Paint paint1 = new Paint(); paint1.setTextSize(10); //(2)设置画笔的颜色 paint1.setColor(Color.BLUE); //(3)drawRect 就是使用画笔绘制一个矩形 前面两个参数代表起始坐标, 也就是左上角 后面两个参数可以标识你想画的长度和宽度 也可以理解为右下角的坐标点。 Rect rect = new Rect(0,0,350,85); canvas.drawRect(rect, paint1); //(1)设置画笔的size Paint paint2 = new Paint(); paint2.setTextSize(10); //(2)设置画笔的颜色 paint2.setColor(Color.GREEN); //(3)drawRect 就是使用画笔绘制一个矩形 前面两个参数代表起始坐标, 也就是左上角 后面两个参数可以标识你想画的长度和宽度 也可以理解为右下角的坐标点。 Rect rect2 = new Rect(350,80,730,160); canvas.drawRect(rect2, paint2); //(1)设置画笔的size Paint paint3 = new Paint(); paint3.setTextSize(10); //(2)设置画笔的颜色 paint3.setColor(Color.RED); //(3)drawRect 就是使用画笔绘制一个矩形 前面两个参数代表起始坐标, 也就是左上角 后面两个参数可以标识你想画的长度和宽度 也可以理解为右下角的坐标点。 Rect rect3 = new Rect(730,160,1080,250); canvas.drawRect(rect3, paint3); } }
注:扫描二维码:最好在AndroidManifest.xml中添加相机使用权限:
<uses-permission android:name="android.permission.CAMERA"></uses-permission>