二維碼呀,現(xiàn)在的項目基本都有的東西,早就有人寫出來了,我也是在用別人的基礎上寫寫心得啊什么的,自己封裝一個還沒那時間和技術去搞,所以這篇文章講的就是怎么用。

呃,圖有點大,好像還暴露了些許信息,算了不管了,就這樣吧。
效果大概就是這樣的。
接下來講講怎么實現(xiàn)的:
首先是下包,用的是ZXing
http://download.csdn.net/download/wiseant/9136099
原諒我忘了之前自己用的是哪個,然后簡書又不能上傳,好了我百度了個版本一樣的發(fā)過來,我是用這個版本的,要是不行你們百度下這個版本吧,正常應該是OK的。
然后是布局文件,這個很簡單
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_scan"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#1c1c1c"
android:orientation="vertical">
<include layout="@layout/head"
android:id="@+id/head"/>
<SurfaceView //這個就是主要的啦
android:id="@+id/surfaceview"
android:background="@drawable/saomiao"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/head"/>
<RelativeLayout //這個本來不必要的,為了那天線沒辦法
android:id="@+id/layout_contain"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginTop="170dp"
android:layout_marginRight="70dp"
android:layout_marginLeft="70dp">
<com.***.**.view.*****//這個就是那條線
android:id="@+id/scanline"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="33dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="180dp"
android:textColor="@color/white"
android:layout_gravity="bottom"
android:gravity="center|top"
android:padding="20dp"
android:text="將醫(yī)生二維碼放入框內,即可自動掃描"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
</RelativeLayout>
這里很多坑,SurfaceView 要是再嵌套一層layout的話,里面的畫面會變形,還有不能全屏(具體什么原因,暫時沒空去找,大神可以指點一下)。至于那個背景框,叫UI截個圖妥妥的不用自己話后面的線。
還有那個ScanLineView 是別人給我的,它的動畫長度略坑,所以勉強調成這樣剛好。
其實最好的方法就是改里面的代碼,但是時間不夠還是算了,將就著用吧。
接下來是activity的代碼了,沒有全部貼,二維碼那塊都在這里了,其實很少東西的
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// setContentView(R.layout.activity_scan);
title.setText("掃描醫(yī)生二維碼");
qrScanManager = new QRScanManager(this); //主要是這玩意而已
layout_contain = (RelativeLayout) findViewById(R.id.layout_contain);
qrScanManager.initWithSurfaceView(this, R.id.surfaceview);
qrScanManager.setBeepResource(R.raw.beep);
Rect rect = initCrop();
qrScanManager.setCropRect(rect);
ScanLineView scanline = (ScanLineView) findViewById(R.id.scanline);
// 動畫效果
TranslateAnimation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 1.0f);
animation.setDuration(4500);
animation.setRepeatCount(-1);
animation.setRepeatMode(Animation.RESTART);
scanline.startAnimation(animation);
}
private Rect initCrop() {
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layout_contain.getLayoutParams();
int x = params.leftMargin;
int y = params.topMargin;
int width = screenWidth - 2 * x;
int height = width;
params.height = height;
layout_contain.setLayoutParams(params);
return new Rect(x, y, width + x, height + y);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
qrScanManager.onResume();
}
@Override
protected void onPause() {
qrScanManager.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
qrScanManager.onDestroy();
super.onDestroy();
}
@Override
public void onScanResult(String content) {
Toast.makeText(this, "結果:" + code[1], Toast.LENGTH_SHORT).show();
}
至于那個ScanLineView 其實要是不要求的話去掉它,代碼就簡單多了,要的人我放上代碼吧
public class ScanLineView extends View {
Paint paint = new Paint();
private float density;// 屏幕密度
private float width, height;// 控件的寬度高度
public ScanLineView(Context context) {
super(context);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ScanLineView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public ScanLineView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public ScanLineView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
density = getResources().getDisplayMetrics().density;
// 去鋸齒
paint.setAntiAlias(true);
paint.setColor(Color.parseColor("#53d555"));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = (int) (250 * density);
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
height = (int) (250 * density);
}
// Log.e("tag", " ------ width:"+width +" height:"+height);
setMeasuredDimension((int) this.width, (int) this.height);
Shader mShader = new LinearGradient( width/2.0f,height,width/2.0f, 0, new int[] {
Color.BLUE, Color.TRANSPARENT}, null,
Shader.TileMode.CLAMP);
paint.setShader(mShader);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 為Paint設置漸變器
// 繪制矩形
canvas.drawRect(0, 0, width, height, paint);
}
}
嗯,就是這個自定義View了,其實代碼很少,東西也不多
掃描的就是這么簡單就搞定了···
然后是生成二維碼,這個更簡單,一個工具類搞定
/**
* 生成一個二維碼圖像
*
* @param url
* 傳入的字符串,通常是一個URL
* @param QR_WIDTH
* 寬度(像素值px)
* @param QR_HEIGHT
* 高度(像素值px)
* @return
*/
public static final Bitmap create2DCoderBitmap(String url, int QR_WIDTH, int QR_HEIGHT) {
try {
// 判斷URL合法性
if (url == null || "".equals(url) || url.length() < 1) {
return null;
}
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// 圖像數(shù)據轉換,使用了矩陣轉換
BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
// 下面這里按照二維碼的算法,逐個生成二維碼的圖片,
// 兩個for循環(huán)是圖片橫列掃描的結果
for (int y = 0; y < QR_HEIGHT; y++) {
for (int x = 0; x < QR_WIDTH; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * QR_WIDTH + x] = 0xff000000;
} else {
pixels[y * QR_WIDTH + x] = 0xffffffff;
}
}
}
// 生成二維碼圖片的格式,使用ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
// 顯示到一個ImageView上面
// sweepIV.setImageBitmap(bitmap);
return bitmap;
} catch (WriterException e) {
Log.i("log", "生成二維碼錯誤" + e.getMessage());
return null;
}
}
生成二維碼,一個bitmap搞定
Bitmap bitmap = QRCodeUtil.create2DCoderBitmap(qrCodeBean.getQRCodeUrl(), 250, 250);
有了bitmap,然后愛放哪放哪,妥妥的就這么簡單搞定了。
說說題外話:
最近少寫了好多篇文章了,說是項目多了,忙不過來,其實還有原因就是自己懶,天氣冷了,人也越變越懶了,本來這篇文章早幾天就想寫的了,拖啊拖啊的就到了今天。
話說,最近逛著逛著簡書,發(fā)現(xiàn)喜歡上了看 堂主姓蔡 這個人寫的故事,大多是鬼故事,都還不錯的樣子。
再有,今晚準備剁手