Android---滑动解锁初步工程
2019-08-26 本文已影响0人
26小瑜儿
准备工作及思路
1.添加控件 9个点 图片 20条线
用:ImageView 显示图片、容器来管理子控件
四种布局:
1)FrameLayout:帧布局
可以实现视图的叠加
2)LinearLayout:线性布局
实现简单的方位层面的视图摆放(上、下、左、右)
3)RelativeLayout:相对布局
可以实现相对于其他视图的布局方式,比线性布局更加灵活
4)ConstraintsLayout:约束布局
比上述布局方式更加灵活多变
关于Touch触发事件:
手触摸事件 将按钮点亮:点亮按钮即为取消隐藏
注:
所有的布局类里面都维护一个LayoutParams
它extends marginLayoutParmas,用于管理当前这个布局容器里面子空间的布局
- Margin : 控件边缘和其他控件的间距 外间距
- POdding : 控件内部和自己的边缘 距离 内间距
- 线性布局方向:
- Orientation Vertical(垂直) Horizontal(水平)
- 权重按比例分配:layout_weight
- 在MarginLayout的基础上添加了对齐
- 当前这个控件和id为v1的控件右边对齐
- android:layout_alignRight="@+id/v1"
*android:layout_alignBottom="@+id/v1" - 约束布局: ConstraintLayout
滑动解锁Demo(未完成版):
最终展示结果:
image.png
点击按键,按键会被点亮
image.pngMainActivity:
image.png
public class MainActivity extends AppCompatActivity {
static float F;
static int numbers=0;
private List<ImageView> points=new ArrayList<ImageView>();
private List<ImageView> Lines=new ArrayList<ImageView>();
float movingX,movingY;
public void onWindowFocusChanged (boolean hasFocus){
float scale = getResources().getDisplayMetrics().density;
F=scale;
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();
//创建横线6条
for(int i = 0;i<2;i++){
for(int j=0;j<3;j++){
//创建一个视图,用于显示线
ImageView lineView = new ImageView(this);
lineView.setVisibility(View.INVISIBLE);
//设置图片
lineView.setBackgroundResource(R.drawable.normal_highlight2);
//创建布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)(x+42*scale)+(int)(99*scale*j);
params.topMargin = (int)(y+170*scale)+(int)(99*scale*i);
rl.addView(lineView,params);
Lines.add(lineView);
}
}
//添加竖线
for(int i = 0;i<3;i++){
for(int j=0;j<2;j++){
//创建一个视图,用于显示线
ImageView lineView = new ImageView(this);
lineView.setVisibility(View.INVISIBLE);
//设置图片
lineView.setBackgroundResource(R.drawable.normal_highlight1);
//创建布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)(x+46.6*scale)+(int)(99*scale*j);
params.topMargin = (int)(y+170*scale)+(int)(99*scale*i);
rl.addView(lineView,params);
Lines.add(lineView);
}
}
//创建右斜线
for(int i = 0;i<2;i++){
for(int j=0;j<2;j++){
//创建一个视图,用于显示线
ImageView lineView = new ImageView(this);
lineView.setVisibility(View.INVISIBLE);
//设置图片
lineView.setBackgroundResource(R.drawable.normal_highlight3);
//创建布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)(x+46.6*scale)+(int)(99*scale*j);
params.topMargin = (int)(y+170*scale)+(int)(99*scale*i);
rl.addView(lineView,params);
Lines.add(lineView);
}
}
//添加左斜线
for(int i = 0;i<2;i++){
for(int j=0;j<2;j++){
//创建一个视图,用于显示线
ImageView lineView = new ImageView(this);
lineView.setVisibility(View.INVISIBLE);
//设置图片
lineView.setBackgroundResource(R.drawable.normal_highlight4);
//创建布局参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = (int)(x+53.3*scale)+(int)(99*scale*j);
params.topMargin = (int)(y+170*scale)+(int)(99*scale*i);
rl.addView(lineView,params);
Lines.add(lineView);
}
}
//添加点
for(int i = 0;i<3;i++){
for(int j=0;j<3;j++){
//获取容器
ImageView dotView;
//创建用于显示点的视图
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) +(int)(99*scale*i);
params.topMargin = (int)(y+162*scale)+(int)(99*scale*j);
//将控件添加到容器中
rl.addView(dotView,params);
points.add(dotView);
}
}
}
image.png
image.png
}
//监听触摸事件
public boolean onTouchEvent( MotionEvent event){
movingX=event.getX();
movingY= event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
checkSelectPoint();
break;
case MotionEvent.ACTION_MOVE:
checkSelectLine();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
public void checkSelectPoint(){
for(int i=0;i<points.size();i++){
float Y = points.get(i).getY();
float X= points.get(i).getX();
if(with(X,Y,movingX,movingY)){
points.get(i).setVisibility(View.VISIBLE);
numbers++;
}
}
}
image.png
public void checkSelectLine(){
for(int i=0;i<Lines.size();i++){
float Y = Lines.get(i).getY();
float X= Lines.get(i).getX();
if(withLine(X,Y,movingX,movingY)){
Lines.get(i).setVisibility(View.VISIBLE);
numbers++;
}
}
}
public static boolean with(float pointX,float pointY,float movingX,float movingY){
return Math.sqrt((5+pointX-movingX)*(5+pointX-movingX)+(99*F+pointY-movingY)*(99*F+pointY-movingY))<50;
}
public static boolean withLine(float pointX,float pointY,float movingX,float movingY){
return Math.sqrt((10+pointX-movingX)*(10+pointX-movingX)+(99*F+pointY-movingY)*(99*F+pointY-movingY))<10;
}
/**
* 安卓中像在容器中添加的控件需要被窗户window计算/测量
* window -> viewGroup ->子控件
* 通常在 onCreate onStrat onResume 无法获取到控件的本身的尺寸
*
* 所有的测量都是在另一个线程操作
* 如果想要获取控件的尺寸
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}