接收验证码用的倒计时
如果需要在倒计时时对ui组件进行操作,像接收手机验证码时的倒计时,不能新建普通进程,产生错误,例如thread之类。
android.util.AndroidRuntimeException: Animators may only be run on Looper threads //子线程内不可改变ui
一个可以用于计时的类,也可以处理固定时间并且要在固定时间间隔刷新的操作。这个类叫做CountDownTimer,idea中点击类名可以查看详细信息:
/**
* Schedule a countdown until a time in the future, with
* regular notifications on intervals along the way.
*
* Example of showing a 30 second countdown in a text field:
*
* <pre class="prettyprint">
* new CountDownTimer(30000, 1000) {
*
* public void onTick(long millisUntilFinished) {
* mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
* }
*
* public void onFinish() {
* mTextField.setText("done!");
* }
* }.start();
* </pre>
*
* The calls to {@link #onTick(long)} are synchronized to this object so that
* one call to {@link #onTick(long)} won't ever occur before the previous
* callback is complete. This is only relevant when the implementation of
* {@link #onTick(long)} takes an amount of time to execute that is significant
* compared to the countdown interval.
*/
翻译过来大概意思就是这是一个执行30秒倒计时的示例。
onTick代表每次间隔时间要执行的内容,onFinsih代表结束时的操作。与thread等一样通过strat方法调用开始。
示例:
public class CountDownReceviceTime extends CountDownTimer {
/**
* @param millisInFuture 时间 The number of millis in the future from the call
* to {@link #start()} until the countdown is done and {@link #onFinish()}
* is called.
* @param countDownInterval 间隔 The interval along the way to receive
* {@link #onTick(long)} callbacks.
*/
private Button button;//要改变的按钮
private String text;//用于获取按钮文本
//构造方法,传入需要内容
public CountDownReceviceTime(long millisInFuture, long countDownInterval, Button button) {
super(millisInFuture, countDownInterval);
this.button = button;//传入按钮
text = button.getText().toString();//获取文本
}
//每次间隔执行
@Override
public void onTick(long millisUntilFinished) {
button.setEnabled(false);//将按钮设为不可点击
int now = (int)millisUntilFinished / 1000;//强制将时间转换为秒
String now1 = String.valueOf(now);
button.setText(now1);//倒计时
}
//结束执行
@Override
public void onFinish() {
//计时结束恢复原内容
button.setText(text);
button.setEnabled(true);
}
}
在其他类中使用new新建并调用start方法即可运行。
//参数,总时间,间隔时间,额外参数(自己设定)
new CountDownReceviceTime(60000, 1000, reGet).start();
重写popUpWindow类,自定义内容
对于一个popUpWindow,本人在Android29api测试,至少要实现几个方法:
//以下方法均可以在外部使用
this.setContentView(view);//视图,该popUpWindow的主要界面
this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);//宽度
this.setHeight(500);//高度
this.setFocusable(true); //聚焦
//背景,不设置的话就是透明的,可以直接看到下面的组件 this.setBackgroundDrawable(drawable对象);
长按事件,让recyclerView响应长按事件弹出菜单项
弹出的菜单项并不是指popUpMenu,而是使用popUpWindow,如果弹出popUpMenu,不能将recyclerView的各项id相同,否则会弹到本页最后一个相同id处。所以要使用popUpWindow。
首先建立一个popUpWindow。然后重写OnLongClick监听接口。注意事项:OnLongClick返回true,那么长按监听只执行长按监听中执行的代码,返回false,还会继续响应其他监听中的事件。
示例:
//将监听写在RecyclerView.Adapter<泛型类,默认为viewholder,可以是自定义的viewholder类>
public class SuiJiAdapter extends RecyclerView.Adapter<SuiJiViewHolder>
implements View.OnLongClickListener
{
private Context context;//上下文
private int size;//生产个数
private LongClickPopUpWindow popupWindow;//弹窗自定义类
private View itemView;
//构造方法
public SuiJiAdapter(Context context, int size)
{
this.context = context;
this.size = size;
}
//必须重写方法,构造一个item
@NonNull
@Override
public SuiJiViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return 返回viewholder对象要和泛型类一致;
}
@Override
public void onBindViewHolder(@NonNull SuiJiViewHolder holder, int position) {
//此处用于绑定数据或执行其它方法
initListener(holder);//建立监听
itemView = holder.getItemView();//获取视图
}
//初始化监听
private void initListener(SuiJiViewHolder holder)
{
//注册视图的长按监听
holder.getItemView().setOnLongClickListener(this);
}
//大小,返回的item个数
@Override
public int getItemCount() {
return size;
}
//长按监听
@Override
public boolean onLongClick(View v) {
switch (v.getId())
{
//响应
case R.id.messageSuiJi:
case R.id.theSuiJi:
{
//创建popUpWindow,可以写在onCreateViewHolder内或其他方法内
popupWindow = new LongClickPopUpWindow(context, null);
//显示,参数可以理解为从最底端弹出
popupWindow.showAtLocation(itemView, Gravity.BOTTOM, 0, 0);
System.out.println(123456);//测试用
return true;//返回true不响应其它监听
}
}
return false;//默认返回
}
}
要监听的控件可以自由选择,注意子控件会遮挡父组件响应,所以上面同时响应了两个id。
布局参数,。。。.LayoutParams.。。。
LayoutParams基本上每个布局都会拥有,但实际上对应的内容的id值都是一样,相同的属性值可以互相串用。
来源:CSDN
作者:嘻嘻哈哈笑呵呵
链接:https://blog.csdn.net/qq_25856179/article/details/103977739