心得感悟
这个Demo还是比较有趣的,虽说之前也做过很多Demo,但都不像一个完整的应用。这个Demo也很有利于我对上一篇文章内容的理解。
实现效果
今天先完成图案解锁的前期准备,配置好需要的各个图片。
所需的图片文件如下:
图案解锁图标 |
---|
提取码:不好意思我给搞忘了( ̄  ̄)σ…(;´д`)ゞ|壁反省 |
记得将图片放在app>res>drawable
目录中。下面给出实现的源码:
activity_main.xml
在xml文件中,我们处理静态的背景图片。
scaleType
是把图片按照指定的大小在ImageView中显示,拉伸显示图片,不保持原比例,填满ImageView
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/root_layout">
<!--背景图片-->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/main_bg"
android:scaleType="fitXY"/>
<!--9个点的背景-->
<ImageView
android:id="@+id/opView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/op_bg"
android:layout_centerInParent="true"/>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// 判断是否已经显示
if (hasFocus){
// 获取容器对象
RelativeLayout rl = findViewById(R.id.root_layout);
// 获取背景视图
ImageView iv = findViewById(R.id.opView);
// 获取x和y的坐标
int x = iv.getLeft();
int y = iv.getTop();
// 获取屏幕密度
float scale = getResources().getDisplayMetrics().density;
// 创建横线 6 条
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
// 创建一个视图 显示线条
ImageView LineView = new ImageView(this);
// 设置图片
LineView.setBackgroundResource(R.drawable.normal_highlight1);
LineView.setVisibility(View.INVISIBLE);
//创建布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)((x + 46*scale) + 99*scale*j);
params.topMargin = (int)((y + 170*scale) + 99*scale*i);
// 将控件添加到容器中
rl.addView(LineView,params);
}
}
// 创建竖线 6 条
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
// 创建一个视图 显示线条
ImageView lineView = new ImageView(this);
// 设置图片
lineView.setBackgroundResource(R.drawable.normal_highlight2);
lineView.setVisibility(View.INVISIBLE);
//创建布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)((x + 43*scale) + 99*scale*j);
params.topMargin = (int)((y + 170*scale) + 99*scale*i);
// 将控件添加到容器中
rl.addView(lineView,params);
}
}
// 创建左右斜线
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
// 创建一个视图 显示线条
ImageView rlineView = new ImageView(this);
// 设置图片
rlineView.setBackgroundResource(R.drawable.normal_highlight3);
rlineView.setVisibility(View.INVISIBLE);
// 设置布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)((x + 42*scale) + 99*scale*j);
params.topMargin = (int)((y + 170*scale) + 99*scale*i);
rl.addView(rlineView,params);
ImageView lLineView = new ImageView(this);
lLineView.setBackgroundResource(R.drawable.normal_highlight4);
lLineView.setVisibility(View.INVISIBLE);
params.leftMargin = (int)((x + 53.3*scale) + 99*scale*j);
params.topMargin = (int)((y + 170*scale) + 99*scale*i);
// 将控件添加到容器中
rl.addView(lLineView,params);
}
}
// 创建 点亮的点 9 个
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
// 创建用于显示点的视图
ImageView dotView = new ImageView(this);
// 隐藏视图
dotView.setVisibility(View.INVISIBLE);
// 显示对应的图片
dotView.setBackgroundResource(R.drawable.selected_dot);
// 创建控件的尺寸
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)((x + 35*scale) + 99*scale*j);
params.topMargin = (int)((y + 164*scale)+ 99*scale*i);
// 将控件添加到容器中
rl.addView(dotView,params);
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
日常超多问
Question1. 运行上面的代码,图案和预期位置仍有偏差
自己再调一调吧
,数据也不会变动很大。
Question2. 运行上面的代码,9个点的图标没有显示出来
通过注释创建点的循环中的,dotView.setVisibility(View.INVISIBLE);
来显示如同本文开头图片的效果。
Question3. for循环的顺序可以更改吗?
由于程序默认后面的图片在最上层,创建9个点的循环必须放到最后
。不知道你有没有发现,创建点、线的循环体中代码惊人地相似,只是部分数据不相同,这是因为它们的放置原理都是一样的。除了点的循环,其他循环的顺序可以更改
。
Question4. 里面的scale有什么用呢?
不同手机的屏幕大小不一致,分辨率也不一致,但是实际图片的大小是不变的。为了让代码在不同手机上都能成功运行,我们通过getResources().getDisplayMetrics().density;
方法获取运行设备的分辨率并赋值给scale,再通过数学计算得出不同设备应该显示的位置。