很多App都有扫描二维码功能,扫描的时候会有一个移动的扫描线,看起来很好实现,不过我网上搜了搜很多方法都是实时绘制出来的,计算点的位置然后重绘出来。我的第一感觉是完全没必要,其实这个东西本质上就是一张贴图加一个平移动画效果,所以就自己做了一个小小例子。
首先是扫描线的素材,这个是直接从微信apk里面扒出来的(其实你如果看中某个App的界面中的某个素材,可以直接下载apk,后缀改成zip解压,然后在里面慢慢找,一般都能找到png图片)。
然后贴出布局文件代码:
- <?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_main"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.example.user.myapplication.MainActivity">
- <View
- android:id="@+id/previewView"
- android:layout_width="300dp"
- android:layout_height="300dp"
- android:layout_centerInParent="true"
- android:background="@color/colorPrimary"/>
-
- <ImageView
- android:id="@+id/scanHorizontalLineImageView"
- android:layout_width="300dp"
- android:layout_height="wrap_content"
- android:src="@drawable/horizontal_line" />
-
- <ImageView
- android:id="@+id/scanVerticalLineImageView"
- android:layout_width="wrap_content"
- android:layout_height="300dp"
- android:src="@drawable/vertical_line"/>
- </RelativeLayout>
界面很简单,previewView主要是用来模拟拍照的预览图,这个预览图提供了动画定位信息,接下来代码会讲。下面是核心代码:
- public class MainActivity extends AppCompatActivity {
-
- private ImageView mScanHorizontalLineImageView;
- private ImageView mScanVerticalLineImageView;
- private View mPreviewView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- mScanHorizontalLineImageView = (ImageView) findViewById(R.id.scanHorizontalLineImageView);
- mScanVerticalLineImageView = (ImageView) findViewById(R.id.scanVerticalLineImageView);
- mPreviewView = findViewById(R.id.previewView);
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
-
- int[] location = new int[2];
-
-
-
- mPreviewView.getLocationInWindow(location);
-
-
- int left = mPreviewView.getLeft();
- int right = mPreviewView.getRight();
- int top = mPreviewView.getTop();
- int bottom = mPreviewView.getBottom();
-
-
- Animation verticalAnimation = new TranslateAnimation(left, left, top, bottom);
- verticalAnimation.setDuration(3000);
- verticalAnimation.setRepeatCount(Animation.INFINITE);
-
-
- mScanHorizontalLineImageView.setAnimation(verticalAnimation);
- verticalAnimation.startNow();
-
-
- Animation horizontalAnimation = new TranslateAnimation(left, right, top, top);
- horizontalAnimation.setDuration(3000);
- horizontalAnimation.setRepeatCount(Animation.INFINITE);
-
-
- mScanVerticalLineImageView.setAnimation(horizontalAnimation);
- horizontalAnimation.startNow();
-
- }
- }
最后的效果大概就是这个样子的:
其实扫描识别二维码这个东西,个人理解就是照相机得到的帧不停地塞给图像处理模块,然后等待图像处理模块回调。