Android每日一坑

    今天在修改以前的项目的时候,碰到了两个坑,一个是动态权限申请的时候,发现相机的权限老是申请不下来,其他权限都可以正常申请,就是相机的权限有问题,后面发现其实不只是相机,第二个是关于ExpandableListView和BaseExpandableListAdapter的使用,**特别是在BaseExpandableListAdapter的view中含有checkbox的时候**,需要注意很多问题。
    先来说第一个,关于动态权限申请的问题,这个问题其实很简单,但是为什么会出现相机的权限老是申请不下来呢,是因为我只是在需要这个权限的时候去动态申请的,但是我并没有在AndroidManifest.xml中去注册这个权限,所以导致每次动态申请的时候都会直接返回-1,也就是用户不同意授权,以下是我在动态权限申请的时候使用的代码,先记录下来,后面也可以直接使用:


    首先判断是否需要动态申请权限,Android6.0以上的系统需要动态申请权限,同时,有的权限可能用户之前已经授予了,也要判断一下
  //判断是否有权限
    private void checkPermission() {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //拍照和文件读取的权限
            String[] permissions = {Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
            for (int i = 0; i < permissions.length; i++) {
                int allow = ContextCompat.checkSelfPermission(this, permissions[i]);
                if (allow != PackageManager.PERMISSION_GRANTED) {
                    showToast("应用需要您的相机和存储权限以更新您的头像");
                    startRequestPermission(permissions);
                    return;
                }
            }
            //程序执行到此处说明所有的权限都是有的
            showChooseCamera();
        }else{
            //不是Android 6.0以上的系统,直接请求
            showChooseCamera();
        }

    }
    当判断到需要动态申请权限的时候去请求权限
  //开始申请权限
    private void startRequestPermission(String[] permissions) {
        ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSION_CODE);
    }
    申请权限之后会回调onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)这个方法,在这个方法里面判断用户是否授予了权限
   @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION_CODE) {
            for (int i = 0; i < grantResults.length; i++) {
                Log.i("TAG", "获取权限的回调是:" +permissions[i]+":" +grantResults[i]+",授予权限是:"+PackageManager.PERMISSION_GRANTED);
            }
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                //用户还是没有授予权限
                if (!shouldShowRequestPermissionRationale(permissions[0])) {
                    showToast("请手动到设置界面授予权限");
                } else {
                    finish();
                }
            } else {
                showChooseCamera();
                showToast("获取权限成功");
            }

        }
    }
    上面就是我动态申请权限的代码,在此记录一下,方便后面使用。需要注意的是:**动态权限也是要在AndroidManifest.xml文件中注册的,如果不注册的话,在系统设置里面是找不到这个权限的,同时动态申请的时候会直接返回-1,告诉你用户拒绝授予权限**。




    关于第二个问题,也就是ExpandableListView和BaseExpandableListAdapter,这个是在做类似于淘宝中的购物车页面的时候遇到了一些问题,主要是checkbox的问题,在此先记录下问题以及解决方案,后面会专门针对购物车这一块写一篇博客。
    (1)首先来说ExpandableListView适用的场景,因为一般的购物车都包括商铺信息和商品信息,也就是一个商铺信息下面有很多商品信息,而商铺信息也是很多的,之前想过使用ExpandableListView的方式来做,但是感觉比较麻烦,后来就使用在一个ListView里面嵌套另一个ListView来做,但是界面比较卡顿,而且比如像勾选了店铺之后,该店铺下面的所有的商品也要自动勾选上,当一个店铺下面所有的商品都已经勾选的时候,这个商铺要自动勾选上等,这些需要都比较难实现,所以最后还是选择使用ExpandableListView来做这一块,做完之后发现ExpandableListView真的挺好用的,最起码界面滑动等不卡顿了,各种信息也能清楚的展示。
    (2)具体来说问题,第一个问题就是:ExpandableListView需要默认处于打开状态,而且点击父view的时候不能关闭,同时去掉父view前面的箭头,这些问题都是在网上找到的解决方案,感谢广大网友:
 //expandListView展开所有视图
    private void openAllExpandView(){
        shopBagExpandAdapter.setData(model);
        shopBagExpandAdapter.notifyDataSetChanged();
        //所有子view处于打开状态
        for(int i = 0; i < mContent.getCount(); i++) {
            mContent.expandGroup(i);
        }
        //去掉箭头
        mContent.setGroupIndicator(null);
        //点击父view不会关闭
        mContent.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
                return true;
            }
        });
    }
    (3)第二个问题就是在我的父view和子view中都出现了checkbox,由于ListView的优化和复用机制,导致当一部分checkbox滑出屏幕的时候,如果这些checkbox处于选中的状态,再次滑回来会回到没有选中的状态,导致数据出现混乱。对于这个问题的解决方案是在填充ExpandableListView的数据集中,加一个参数,用来指定当前的item是否处于选中的状态,每次根据这个值来对ExpandableListView的状态进行判断,不管是父view还是子view都可以通过这种方式实现。

    (4)第三个问题在于checkbox的状态监听,不能使用OnCheckedChangeListener这个接口去监听checkbox的状态,使用这个接口监听还是会造成数据混乱。但是checkbox还是要切换状态,这里有两种方式,第一种就是对checkbox添加点击事件的监听,第二个方法是对checkbox所在的布局添加点击事件的监听,这两种方法还是有一点区别的,因为一般使用checkbox.setChecked(true/false)来设置checkbox的选中状态,那在设置之前就要知道当前的checkbox是选中还是没选中,可以通过checkbox.isChecked()来获取当前checkbox的选中状态,第一种方式是点击之后checkbox已经改变了,直接使用isChecked()获取到的值即可,第二种方式由于不是在checkbox上点击,所以获取到的是还没有改变的值,需要取反。也就是:第一种方式不需要setChecked()来设置选中状态,要设置的话就是用checkbox.setChecked(checkbox.isChecked()),第二种方式需要手动设置checkbox的选中状态,checkbox.setChecked(!checkbox.isChecked())

    (5)第四个问题在于界面更新,其实简单的使用notifyDataSetChanged()就可以更新界面了,网上很多人说的打开关闭一次父view个人感觉并不靠谱,因为前面设置了父view永远处于打开状态,所以导致使用这种方式的话会出现getChildCount()下标越界异常,因为父view处于选中状态的时候子view也要跟着改变,所以一般来说,如果设置没有问题的话,父view选中状态后,使用notifyDataSetChanged()可以直接更新界面,没有任何问题,同理,子view改变父view要更新界面也是一样,使用notifyDataSetChanged()完全可以了。

      (6)后面项目中还遇到了一些其他问题,不过都是一些逻辑上的问题,还有一些记不起来了,暂时就到这里,关于购物车页面我会在下一篇博客更新。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值