当前位置: 首页 > news >正文

没域名 打开网站中小型网站建设方案

没域名 打开网站,中小型网站建设方案,免费观看电视在线高清,备案网站负责人最近项目上用到一个密码加锁功能#xff0c;需要一个数字密码界面#xff0c;就想着封装成一个View来方便管理和使用。 废话不多说#xff0c;先上最终效果图#xff1a; 思路 整体可分为2个部分来实现#xff0c;1.顶部是4个密码位的填充#xff1b;2.数字键盘部分。整…最近项目上用到一个密码加锁功能需要一个数字密码界面就想着封装成一个View来方便管理和使用。 废话不多说先上最终效果图 思路 整体可分为2个部分来实现1.顶部是4个密码位的填充2.数字键盘部分。整体可以是一个纵向LinearLayout4个密码位用横向LinearLayout即可键盘由于是宫格形式因此可用GridLayout来布局。由于密码位和键盘数字都是以圆圈为背景这里采用自定义一个圆形背景ImageView来使用。 实现 1.页面布局 首先定义一个圆形背景的ImageView由于最终实现的效果是点击的时候要填充圆背景非点击状态下是空心圆因此可通过改变Paint的style来动态更改显示: /** * 圆形背景ImageView设置实心或空心 */ public class CircleImageView extends ImageView{ private Paint mPaint; private int mWidth; private int mHeight; public CircleImageView(Context context) { this(context, null); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } public void initView(Context context){ mPaint new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(mPanelColor); mPaint.setStrokeWidth(mStrokeWidth); mPaint.setAntiAlias(true); } Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth w; mHeight h; } Override public void draw(Canvas canvas) { canvas.drawCircle(mWidth/2, mHeight/2, mWidth/2 - 6, mPaint); super.draw(canvas); } /** * 设置圆为实心状态 */ public void setFillCircle(){ mPaint.setStyle(Paint.Style.FILL); invalidate(); } /** * 设置圆为空心状态 */ public void setStrokeCircle(){ mPaint.setStyle(Paint.Style.STROKE); invalidate(); } } 可以看到在onDraw中绘制了一个圆默认为空心状态定义setFillCircle和setStrokeCircle这两个方法以便外界可以方便地切换圆为实心或者空心。 圆形ImageView定义好了开始添加密码位布局如下: inputResultView new LinearLayout(context); for(int i0; i4; i){ CircleImageView mResultItem new CircleImageView(context); mResultIvList.add(mResultItem); LinearLayout.LayoutParams params new LinearLayout.LayoutParams(mResultIvRadius, mResultIvRadius); params.leftMargin dip2px(context, 4); params.rightMargin dip2px(context, 4); mResultItem.setPadding(dip2px(context, 2),dip2px(context, 2),dip2px(context, 2),dip2px(context, 2)); mResultItem.setLayoutParams(params); inputResultView.addView(mResultItem); } LinearLayout.LayoutParams params new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity Gravity.CENTER_HORIZONTAL; params.bottomMargin dip2px(context, 34); inputResultView.setLayoutParams(params); addView(inputResultView); 接着添加数字键盘部分的布局: GridLayout numContainer new GridLayout(context); numContainer.setColumnCount(3); for(int i0; inumArr.length; i){ RelativeLayout numItem new RelativeLayout(context); numItem.setPadding(mPaddingLeftRight,mPaddingTopBottom,mPaddingLeftRight,mPaddingTopBottom); RelativeLayout.LayoutParams gridItemParams new RelativeLayout.LayoutParams(mNumRadius, mNumRadius); gridItemParams.addRule(CENTER_IN_PARENT); final TextView numTv new TextView(context); numTv.setText(numArr[i]); numTv.setTextColor(mPanelColor); numTv.setTextSize(30); numTv.setGravity(Gravity.CENTER); numTv.setLayoutParams(gridItemParams); final CircleImageView numBgIv new CircleImageView(context); numBgIv.setLayoutParams(gridItemParams); numItem.addView(numBgIv); numItem.addView(numTv); numContainer.addView(numItem); if(i 9){ numItem.setVisibility(INVISIBLE); } } //删除按钮 RelativeLayout deleteItem new RelativeLayout(context); deleteItem.setPadding(mPaddingLeftRight,mPaddingTopBottom,mPaddingLeftRight,mPaddingTopBottom); RelativeLayout.LayoutParams gridItemParams new RelativeLayout.LayoutParams(mNumRadius, mNumRadius); gridItemParams.addRule(CENTER_IN_PARENT); //假如删除按钮是设置自定义图片资源的话可用注释这段 //ImageView deleteIv new ImageView(context); //deleteIv.setImageResource(R.drawable.icn_delete_pw); //deleteIv.setLayoutParams(gridItemParams); //deleteItem.addView(deleteIv); TextView deleteTv new TextView(context); deleteTv.setText(Delete); deleteTv.setTextColor(mPanelColor); deleteTv.setTextSize(dip2px(context, 8)); deleteTv.setLayoutParams(gridItemParams); deleteTv.setGravity(Gravity.CENTER); deleteItem.addView(deleteTv); numContainer.addView(deleteItem); LinearLayout.LayoutParams gridParams new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); gridParams.gravity Gravity.CENTER_HORIZONTAL; numContainer.setLayoutParams(gridParams); addView(numContainer); 数字键盘这里用一个数组存数字内容遍历添加注意此处由于第10个的子View的时候是空白的所以当遍历到第10个元素的时候可以将其隐藏。遍历完后再单独添加删除按钮。 2.输入逻辑 页面布局完成了接下来就是密码输入的逻辑部分最终的效果是每点击一次数字密码位就填充一个每点击删除按钮一次密码位就回退一个输入4个数字之后即完成输入获取结果并重置密码位。这里用一个StringBuilder变量来记录当前已输入的密码每次添加就append进去每次删除就调用deleteCharAt。 由于点击数字按下的时候填充松开的时候为空心状态所以可以在ACTION_DOWN和ACTION_UP事件中分别操作: numTv.setOnTouchListener(new OnTouchListener() { Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: numBgIv.setFillCircle(); numTv.setTextColor(Color.WHITE); if(mPassWord.length() 4){ mPassWord.append(numTv.getText()); mResultIvList.get(mPassWord.length()-1).setFillCircle(); if(mInputListener!null mPassWord.length() 4){ //已完整输入4个 } } break; case MotionEvent.ACTION_UP: numBgIv.setStrokeCircle(); numTv.setTextColor(mPanelColor); break; } return true; } }); 每次点击的时候判断当前已输入的密码位是否已经超过4位如果没超过就继续追加。如果等于4就说明输入完成此时的mPassWord的内容就是最终的密码可以用一个接口将其回调出去方便Activity中获取输入的密码 /** * 监听输入完毕的接口 */ private InputListener mInputListener; public void setInputListener(InputListener mInputListener) { his.mInputListener mInputListener; } public interface InputListener{ void inputFinish(String result); } 然后在上面的ACTION_DOWN中输入数字等于4的时候回调该接口 if(mInputListener!null mPassWord.length() 4){ mInputListener.inputFinish(mPassWord.toString()); } 另外删除的操作单独封装为一个方法 /** * 删除 */ public void delete(){ if(mPassWord.length() 0){ return; } mResultIvList.get(mPassWord.length()-1).setStrokeCircle(); mPassWord.deleteCharAt(mPassWord.length()-1); } **注意点**当前无输入密码时直接return不作任何操作假如已有输入数字就删除最尾部的那个数字。 最后还要考虑一种情况即用户输入密码错误时的一些反馈参照平时的习惯一般是4个密码位左右摆动并且手机震动效果震动结束之后当前存储的密码位重置为初始状态如下 /** * 输入错误的状态显示(包括震动密码位左右摇摆效果重置密码位) */ public void showErrorStatus(){ mVibrator.vibrate(new long[]{100,100,100,100},-1); ListAnimator animators new ArrayList (); ObjectAnimator translationXAnim ObjectAnimator.ofFloat(inputResultView, translationX, -50.0f,50.0f,-50.0f,0.0f); translationXAnim.setDuration(400); animators.add(translationXAnim); AnimatorSet btnSexAnimatorSet new AnimatorSet(); btnSexAnimatorSet.playTogether(animators); btnSexAnimatorSet.start(); btnSexAnimatorSet.addListener(new Animator.AnimatorListener() { Override public void onAnimationStart(Animator animation) { } Override public void onAnimationEnd(Animator animation) { resetResult(); } Override public void onAnimationCancel(Animator animation) { } Override public void onAnimationRepeat(Animator animation) { } }); } 可以看到在onAnimationEnd中调用了resetResult即动画结束时重置密码resetResult方法如下 /** * 重置密码输入 */ public void resetResult(){ for(int i0; imResultIvList.size(); i){ mResultIvList.get(i).setStrokeCircle(); } mPassWord.delete(0, 4); } 遍历所有密码位View设置为空心并且删除当前mPassWord变量存储的所有内容。 完整代码 完整的自定义数字密码锁代码如下 package com.example.zjyang.viewtest.view; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.app.Service; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Vibrator; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.GridLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import static android.widget.RelativeLayout.CENTER_HORIZONTAL; import static android.widget.RelativeLayout.CENTER_IN_PARENT; /** * Created by IT_ZJYANG on 2018/1/22. * 数字解锁键盘View */ public class NumLockPanel extends LinearLayout { private String[] numArr new String[]{1,2,3,4,5,6,7,8,9, , 0}; private int mPaddingLeftRight; private int mPaddingTopBottom; //4个密码位ImageView private ArrayListCircleImageView mResultIvList; private LinearLayout inputResultView; //存储当前输入内容 private StringBuilder mPassWord; //振动效果 private Vibrator mVibrator; //整个键盘的颜色 private int mPanelColor; //4个密码位的宽度 private int mResultIvRadius; //数字键盘的每个圆的宽度 private int mNumRadius; //每个圆的边界宽度 private int mStrokeWidth; public NumLockPanel(Context context) { this(context, null); } public NumLockPanel(Context context, AttributeSet attrs) { this(context, attrs, 0); } public NumLockPanel(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaddingLeftRight dip2px(context, 21); mPaddingTopBottom dip2px(context, 10); mPanelColor Color.BLACK; //颜色代码可采用Color.parse(#000000); mResultIvRadius dip2px(context, 20); mNumRadius dip2px(context, 66); mStrokeWidth dip2px(context, 2); mVibrator (Vibrator)context.getSystemService(Service.VIBRATOR_SERVICE); mResultIvList new ArrayList (); mPassWord new StringBuilder(); setOrientation(VERTICAL); setGravity(CENTER_HORIZONTAL); initView(context); } public void initView(Context context){ //4个结果号码 inputResultView new LinearLayout(context); for(int i0; i4; i){ CircleImageView mResultItem new CircleImageView(context); mResultIvList.add(mResultItem); LinearLayout.LayoutParams params new LinearLayout.LayoutParams(mResultIvRadius, mResultIvRadius); params.leftMargin dip2px(context, 4); params.rightMargin dip2px(context, 4); mResultItem.setPadding(dip2px(context, 2),dip2px(context, 2),dip2px(context, 2),dip2px(context, 2)); mResultItem.setLayoutParams(params); inputResultView.addView(mResultItem); } LinearLayout.LayoutParams params new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity Gravity.CENTER_HORIZONTAL; params.bottomMargin dip2px(context, 34); inputResultView.setLayoutParams(params); addView(inputResultView); //数字键盘 GridLayout numContainer new GridLayout(context); numContainer.setColumnCount(3); for(int i0; inumArr.length; i){ RelativeLayout numItem new RelativeLayout(context); numItem.setPadding(mPaddingLeftRight,mPaddingTopBottom,mPaddingLeftRight,mPaddingTopBottom); RelativeLayout.LayoutParams gridItemParams new RelativeLayout.LayoutParams(mNumRadius, mNumRadius); gridItemParams.addRule(CENTER_IN_PARENT); final TextView numTv new TextView(context); numTv.setText(numArr[i]); numTv.setTextColor(mPanelColor); numTv.setTextSize(30); numTv.setGravity(Gravity.CENTER); numTv.setLayoutParams(gridItemParams); final CircleImageView numBgIv new CircleImageView(context); numBgIv.setLayoutParams(gridItemParams); numTv.setOnTouchListener(new OnTouchListener() { Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: numBgIv.setFillCircle(); numTv.setTextColor(Color.WHITE); if(mPassWord.length() 4){ mPassWord.append(numTv.getText()); mResultIvList.get(mPassWord.length()-1).setFillCircle(); if(mInputListener!null mPassWord.length() 4){ mInputListener.inputFinish(mPassWord.toString()); } } break; case MotionEvent.ACTION_UP: numBgIv.setStrokeCircle(); numTv.setTextColor(mPanelColor); break; } return true; } }); numItem.addView(numBgIv); numItem.addView(numTv); numContainer.addView(numItem); if(i 9){ numItem.setVisibility(INVISIBLE); } } //删除按钮 RelativeLayout deleteItem new RelativeLayout(context); deleteItem.setPadding(mPaddingLeftRight,mPaddingTopBottom,mPaddingLeftRight,mPaddingTopBottom); RelativeLayout.LayoutParams gridItemParams new RelativeLayout.LayoutParams(mNumRadius, mNumRadius); gridItemParams.addRule(CENTER_IN_PARENT); //假如删除按钮是设置自定义图片资源的话可用注释这段 //ImageView deleteIv new ImageView(context); //deleteIv.setImageResource(R.drawable.icn_delete_pw); //deleteIv.setLayoutParams(gridItemParams); //deleteItem.addView(deleteIv); TextView deleteTv new TextView(context); deleteTv.setText(Delete); deleteTv.setTextColor(mPanelColor); deleteTv.setTextSize(dip2px(context, 8)); deleteTv.setLayoutParams(gridItemParams); deleteTv.setGravity(Gravity.CENTER); deleteItem.addView(deleteTv); numContainer.addView(deleteItem); deleteTv.setOnClickListener(new OnClickListener() { Override public void onClick(View v) { delete(); } }); LinearLayout.LayoutParams gridParams new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); gridParams.gravity Gravity.CENTER_HORIZONTAL; numContainer.setLayoutParams(gridParams); addView(numContainer); } /** * 输入错误的状态显示(包括震动密码位左右摇摆效果重置密码位) */ public void showErrorStatus(){ mVibrator.vibrate(new long[]{100,100,100,100},-1); ListAnimator animators new ArrayList (); ObjectAnimator translationXAnim ObjectAnimator.ofFloat(inputResultView, translationX, -50.0f,50.0f,-50.0f,0.0f); translationXAnim.setDuration(400); animators.add(translationXAnim); AnimatorSet btnSexAnimatorSet new AnimatorSet(); btnSexAnimatorSet.playTogether(animators); btnSexAnimatorSet.start(); btnSexAnimatorSet.addListener(new Animator.AnimatorListener() { Override public void onAnimationStart(Animator animation) { } Override public void onAnimationEnd(Animator animation) { resetResult(); } Override public void onAnimationCancel(Animator animation) { } Override public void onAnimationRepeat(Animator animation) { } }); } /** * 删除 */ public void delete(){ if(mPassWord.length() 0){ return; } mResultIvList.get(mPassWord.length()-1).setStrokeCircle(); mPassWord.deleteCharAt(mPassWord.length()-1); } /** * 重置密码输入 */ public void resetResult(){ for(int i0; imResultIvList.size(); i){ mResultIvList.get(i).setStrokeCircle(); } mPassWord.delete(0, 4); } /** * 监听输入完毕的接口 */ private InputListener mInputListener; public void setInputListener(InputListener mInputListener) { this.mInputListener mInputListener; } public interface InputListener{ void inputFinish(String result); } /** * dip/dp转像素 * * param dipValue * dip或 dp大小 * return 像素值 */ public static int dip2px(Context context, float dipValue) { DisplayMetrics metrics context.getResources().getDisplayMetrics(); return (int) (dipValue * (metrics.density) 0.5f); } /** * 圆形背景ImageView设置实心或空心 */ public class CircleImageView extends ImageView{ private Paint mPaint; private int mWidth; private int mHeight; public CircleImageView(Context context) { this(context, null); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } public void initView(Context context){ mPaint new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(mPanelColor); mPaint.setStrokeWidth(mStrokeWidth); mPaint.setAntiAlias(true); } Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth w; mHeight h; } Override public void draw(Canvas canvas) { canvas.drawCircle(mWidth/2, mHeight/2, mWidth/2 - 6, mPaint); super.draw(canvas); } /** * 设置圆为实心状态 */ public void setFillCircle(){ mPaint.setStyle(Paint.Style.FILL); invalidate(); } /** * 设置圆为空心状态 */ public void setStrokeCircle(){ mPaint.setStyle(Paint.Style.STROKE); invalidate(); } } } 使用 在Activity的布局文件中 ?xml version1.0 encodingutf-8? RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:toolshttp://schemas.android.com/tools android:idid/activity_main android:layout_widthmatch_parent android:layout_heightmatch_parent android:background#ffffff tools:contextcom.example.zjyang.viewtest.MainActivity com.example.zjyang.viewtest.view.NumLockPanel android:idid/num_lock android:layout_widthmatch_parent android:layout_heightwrap_content android:layout_marginTop30dp /com.example.zjyang.viewtest.view.NumLockPanel /RelativeLayout 在代码中监听输入的密码结果 public class MainActivity extends AppCompatActivity { private NumLockPanel mNumLockPanel; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNumLockPanel (NumLockPanel) findViewById(R.id.num_lock); mNumLockPanel.setInputListener(new NumLockPanel.InputListener() { Override public void inputFinish(String result) { //此处result即为输入结果 Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); //错误效果示例 mNumLockPanel.showErrorStatus(); } }); } } 最后在自定义View构造方法中初始化了圆圆和数字的颜色风格以及空心圆的边界粗细大小可根据需求自行更改。 更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》 1.Android车载应用开发系统学习指南附项目实战 2.Android Framework学习指南助力成为系统级开发高手 3.2023最新Android中高级面试题汇总解析告别零offer 4.企业级Android音视频开发学习路线项目实战附源码 5.Android Jetpack从入门到精通构建高质量UI界面 6.Flutter技术解析与实战跨平台首要之选 7.Kotlin从入门到实战全方面提升架构基础 8.高级Android插件化与组件化含实战教程和源码 9.Android 性能优化实战360°全方面性能调优 10.Android零基础入门到精通高手进阶之路 敲代码不易关注一下吧。ღ( ´ᴗ )
http://www.pierceye.com/news/537138/

相关文章:

  • 哪里有做网站推广的宁波招聘网站开发
  • 建站工具帝国双语网站开发
  • 呼和浩特企业网站建设赞叹天河网站建设公司
  • 新郑做网站公司吉林省建设项目招标网
  • 深圳做网站哪里最好南宁seo外包平台
  • 新开传奇网站推荐做百度推广怎么做才能有电话
  • 文件夹里内容做网站的分类做网站上线一般要多久
  • 企业网站页头背景图河南网络优化服务
  • 成品网站nike源码免费现在装宽带要多少钱
  • 綦江建设银行网站外贸精品网站建设
  • 互动性的网站做第一个php网站
  • 移动网站开发视频怎样嵌入遵义市公共资源交易平台
  • 教做美食的视频网站青岛手机网站建设报价
  • 校园网站建设网成功做网站
  • 网站策划方案如何做网页设计师职业认知
  • 助孕网站优化推广项目名称有创意大全
  • 百度制作网站福州做商城网站公司
  • 周口师范做网站做类似昵图网网站
  • 岳阳企业网站建设网站服务器暂时不可用怎么办
  • 网站的站点的管理系统网站建设组织架构
  • 怎么制作网站视频教程wordpress 导入图片
  • 淘宝网发布网站建设wordpress不能翻页
  • 怎么样可以做网站wordpress gallery widget
  • 湖北网站推广公司技巧自己做app的软件
  • 网站梦打开又提示无法访问dw网页设计代码茶文化
  • 阳江营销型网站建设wordpress防攻击插件
  • 深圳电信网络建站东莞房价2022最新价格
  • 昆山营销型网站建设温州网上商城网站建设
  • 网站html动态效果asp化妆品网站源码
  • 丹东网站seo国家企业工商网查询