Skip to content

Latest commit

 

History

History
344 lines (283 loc) · 13 KB

待办事项开发中遇到的问题及解决办法.md

File metadata and controls

344 lines (283 loc) · 13 KB

一些踩到的坑:

1.

在数据库查询时我发现:布尔型变量得用“1”和“0”来判断true和false。切记切记,下回不要踩坑了。

2.

context光是Context出来是没用的,只不过是一个空的值,会空指针报错的。

Context context = parent.getContext();
            int position = holder.getAbsoluteAdapterPosition();
            ToDoList toDoList = mToDoList.get(position);
            Intent intent = new Intent(context, QueryAndChange.class);
            intent.putExtra("content",toDoList);
            context.startActivity(intent);

应该得这样才能够使其发挥作用

3.

在报错原因出在build.gradle时,最好还是自行上google找寻解决方法。(这样来的最快,效率最高)

4.

没事别手贱删除乱七八糟的东西,差点得整个项目全部重做了(只能说是惨痛的教训)。

5.

让内容在主界面展示的方法:

先把需要展示的东西全部储存在数据库中,再把recyclerview的适配器做好,在MainActivity中把相应的事件查询到,添加到需要展示的类中,就能够展示出来了。

6.

表关联后对应的user_id就是User表中的数据的id。

7.

在UI设计方面有material库可以让我们有更多的选择,让应用界面更加优美,功能更加强大,主要是方便好用。

8.

Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(WelcomeActivity.this, Login.class);
                startActivity(intent);
                WelcomeActivity.this.fileList();
                finish();
            }
        },1000);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event){
        if (keyCode == KeyEvent.KEYCODE_BACK){
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

一般应用都会有个开始页面,实现开始页面的代码如上,只需要自己布局出界面就能运行,“,1000”处是设置停留时间的,不宜太长也不宜太短,最好还是自己调试过后选出最佳时间。

9.

UI设计时CardView布局非常适合呈现线性排列的方块,这样看起来更有层次感,更加简洁。

10.

在数据库中添加新内容后一定要记得更新数据库的版本号(切记)!!!

11.

使用navigationview的时候常常会把用户数据显示在nav_header上,但是不能在方法里面设值。否则只能点击方法后才能完成赋值。但是在外面直接赋值的话又会找不到TextView的id。因为navigation有特殊的方法。需要这样才能找到并完成赋值:

user_account = navigationView.getHeaderView(0).findViewById(R.id.this_account);
User user_information = LitePal.where("online = ?",String.valueOf(1)).findFirst(User.class);
user_name = navigationView.getHeaderView(0).findViewById(R.id.user_name);
user_name.setText(user_information.getName().toString());
user_account.setText(user_information.getAccount().toString());

12.

监听器不需要时可以取消,目前最为直接有效的是:

setOnClickListener(null);

13.

倒计时器可以用CountDownTimer类来实现,其本身能够定义开始事件,进行时的事件,以及结束时的事件。

 private long mInitialTimeLeft;
    private long mTimeLeft;

    public MyCountDownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        mInitialTimeLeft = millisInFuture;
        mTimeLeft = millisInFuture;
    }
    @Override
    public void onTick(long millisUntilFinished) {
        mTimeLeft = millisUntilFinished;
    }
    @Override
    public void onFinish() {
    }

但是没有快进,暂停,继续,重置,这些功能,需要自己在CountDownTimer的子类中再来书写这些方法

public void pause() {
        this.cancel();
        mTimeLeft = this.mInitialTimeLeft - mTimeLeft;
    }
    public void resume() {
        this.cancel();
        this.mInitialTimeLeft = mTimeLeft;
        this.start();
    }

14.

随机设置背景图的办法:先把背景图找好,然后把背景图的id放进一个数组,再从数组中随机取值设为背景。

15.

需要让数据在不同活动之间传递并完成即时更新,EventBus确实是一个很好用的办法(在另一篇笔记里有详细使用方法)

16.

在设置头像功能时,第一行代码上的教程做法思路很清晰,但是实际很繁琐复杂,而且在应对目前系统有较大变动的情况下还是很吃力。因此我找寻到了一种更为便捷,简单的办法。在权限申请方面和书上没有较大差别,可以沿用书上的方法来申请权限。如下:

private void setHeaderFromCamera() {
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){
            doTake();
        } else {
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},1);
        }
    }
    private void setHeaderFromAlbum() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
            openAlbum();
        } else {
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                doTake();
            } else {
                Toast.makeText(this, "无使用相机权限", Toast.LENGTH_SHORT).show();
            }
        }
        if (requestCode == 2){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openAlbum();
            } else {
                Toast.makeText(this, "无访问相册权限", Toast.LENGTH_SHORT).show();
            }
        }
    }

在申请到了权限后就到了选用了,如果要调用相机拍照的话,要将拍的照片先存到文件中,再通过内容提供器拿到图片的uri,之后就和书上不一样了,书上是返回这个uri再解析为文件路径加载图片,而我们其实可以直接使用glide这个图片处理工具。用法如下:

 Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);

首先调用Glide.with()方法并传入一个Context、Activity或Fragment参数,然后调用load()方法去加载图片,可以是一个URL地址,也可以是一个本地路径,或者是一个资源id,最后调用into()方法将图片设置到具体某一个ImageView中就可以了。

然后将图片的uri存储在文件中(因为我不确定uri会不会让数据库爆掉,之前直接把bitmap存到数据库中导致炸库了),将那个文件名以用户id来命名(确保文件的唯一性,不会用户之间混淆),将这个文件名存于数据库中,在加载主页面的时候根据数据库中的文件名找出文件中的uri,再用glide加载出图片就好啦。

在相册选取图片同样如此。我之前反复试过以路径转换为bitmap再加载出图片,经过一下午的测试,虚拟机能行,真机不能(应该是因为系统导致)所以我试着运用uri直接加载图片,发现用glide处理真的是太方便了,可以省去复杂繁琐的uri和路径之间的转换,还可以不用理会系统的读取权限等一系列七七八八的东西。直接从相册获取uri然后加载显示就好。

用相机或相册选取并显示的完整代码如下:

private void setHeaderFromCamera() {
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){
            doTake();
        } else {
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},1);
        }
    }
    private void setHeaderFromAlbum() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
            openAlbum();
        } else {
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                doTake();
            } else {
                Toast.makeText(this, "无使用相机权限", Toast.LENGTH_SHORT).show();
            }
        }
        if (requestCode == 2){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openAlbum();
            } else {
                Toast.makeText(this, "无访问相册权限", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void doTake() {
        File imageHeader = new File(getExternalCacheDir(),"imageOut.jpeg");
        if (imageHeader.exists()) {
            imageHeader.delete();
        }
        try {
            imageHeader.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (Build.VERSION.SDK_INT > 24) {
            imageUri = FileProvider.getUriForFile(this,"com.example.needtodo.MainActivity.fileprovider",imageHeader);
        } else {
            imageUri = Uri.fromFile(imageHeader);
        }
        Intent intent = new Intent();
        intent.setAction("android.media.action.IMAGE_CAPTURE");
        intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
        startActivityForResult(intent,TAKE_PHOTO_REQUEST);
    }
    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,CHOOSE_PHOTO_REQUEST);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TAKE_PHOTO_REQUEST) {
            if (resultCode == RESULT_OK) {
                    Glide.with(this).load(imageUri).into(headImage);
                    save(imageUri);
            }
        } else if (requestCode == CHOOSE_PHOTO_REQUEST) {
            if (resultCode == RESULT_OK) {
                Uri uri = data.getData();
                displayImage(uri);
            }
        }
    }

    private void displayImage(Uri uri) {
        if (uri != null) {
            Glide.with(this).load(uri).into(headImage);
            save(uri);
        }
    }

存储步骤如下;

private void save(Uri inputText) {
        User name_file = LitePal.where("online = ?",String.valueOf(1)).findFirst(User.class);
        if(name_file.getHeadImage_File() == null){
            name_file.setHeadImage_File(String.valueOf(name_file.getId()));
            name_file.save();
        }
        else if(name_file.getHeadImage_File() != null){
            name_file.setHeadImage_File(String.valueOf(name_file.getId()));
            name_file.updateAll("online = ?",String.valueOf(1));
        }
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            out = openFileOutput(name_file.getHeadImage_File(), Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(String.valueOf(inputText));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer !=null) {
                    writer.close();
                    Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

取出步骤如下:

private String load (String name) {
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();
        try {
            in = openFileInput(name);
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine())!=null) {
                content.append(line);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return content.toString();
    }

关于图片设置及保存暂时就告一段落。