Android学习日志2020-1-14

烂漫一生 提交于 2020-01-14 20:37:13

接收验证码用的倒计时

    如果需要在倒计时时对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值都是一样,相同的属性值可以互相串用。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!