在数据库查询时我发现:布尔型变量得用“1”和“0”来判断true和false。切记切记,下回不要踩坑了。
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);
应该得这样才能够使其发挥作用
在报错原因出在build.gradle时,最好还是自行上google找寻解决方法。(这样来的最快,效率最高)
没事别手贱删除乱七八糟的东西,差点得整个项目全部重做了(只能说是惨痛的教训)。
先把需要展示的东西全部储存在数据库中,再把recyclerview的适配器做好,在MainActivity中把相应的事件查询到,添加到需要展示的类中,就能够展示出来了。
表关联后对应的user_id就是User表中的数据的id。
在UI设计方面有material库可以让我们有更多的选择,让应用界面更加优美,功能更加强大,主要是方便好用。
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”处是设置停留时间的,不宜太长也不宜太短,最好还是自己调试过后选出最佳时间。
UI设计时CardView布局非常适合呈现线性排列的方块,这样看起来更有层次感,更加简洁。
在数据库中添加新内容后一定要记得更新数据库的版本号(切记)!!!
使用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());
监听器不需要时可以取消,目前最为直接有效的是:
setOnClickListener(null);
倒计时器可以用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();
}
随机设置背景图的办法:先把背景图找好,然后把背景图的id放进一个数组,再从数组中随机取值设为背景。
需要让数据在不同活动之间传递并完成即时更新,EventBus确实是一个很好用的办法(在另一篇笔记里有详细使用方法)
在设置头像功能时,第一行代码上的教程做法思路很清晰,但是实际很繁琐复杂,而且在应对目前系统有较大变动的情况下还是很吃力。因此我找寻到了一种更为便捷,简单的办法。在权限申请方面和书上没有较大差别,可以沿用书上的方法来申请权限。如下:
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();
}
关于图片设置及保存暂时就告一段落。