今天花费将近3个多小时的时间,将以前的Android知识回顾了一遍,同时自己针对自己的任务做了一个小Demo。
主要用到的是ViewModel来存储页面数据,Respositry仓库来进行数据的增删改查,还有一个Database数据库,一个Dao和展示数据的Adapter
在数据的增删改查利用的事AsynceTask的副线程,创建singleton单实例数据库。
在实现的过程中,出现的问题有:
对AsynceTask的线程问题不熟悉,一开始的做法是直接在活动中强制在主线程执行增删改查,查了相关操作后才发现可以用AsynceTask的副线程,即安全又可靠。
Word.java
package com.example.roombasic;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity
public class Word {
@PrimaryKey(autoGenerate = true)
private int id;
private String word;
private String meaning;
public Word(String word, String meaning) {
this.word = word;
this.meaning = meaning;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getMeaning() {
return meaning;
}
public void setMeaning(String meaning) {
this.meaning = meaning;
}
}
View Code
WordDao.java
package com.example.roombasic;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
import java.util.ListIterator;
@Dao
public interface WordDao {
@Insert
void insertWord(Word... words);
@Update
void updateWord(Word... words);
@Delete
void deleteWord(Word... words);
@Query("delete from word")
void deleteALLWord();
@Query("select * from word order by id desc")
//List<Word> getAllWord();
LiveData<List<Word>>getAllWordsLive();
}
View Code
WordDataBase.java
package com.example.roombasic;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {Word.class},version=1,exportSchema = false)
//singleton单实例数据库
public abstract class WordDatabase extends RoomDatabase {
private static WordDatabase INSTANCE;
static synchronized WordDatabase getDatebase(Context context){
if(INSTANCE==null){
INSTANCE= Room.databaseBuilder(context.getApplicationContext(),WordDatabase.class,"word_database")
.build();
}
return INSTANCE;
}
public abstract WordDao getWordDao();
}
View Code
WordRepository.java(仓库类)
package com.example.roombasic;
import android.content.Context;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import java.util.List;
//仓库类,用来管理viewmodel的增删改查操作
class WordRepository {
private LiveData<List<Word>> allWordsLive;
private WordDao wordDao;
WordRepository(Context context) {
WordDatabase wordDatabase = WordDatabase.getDatebase(context.getApplicationContext());
wordDao = wordDatabase.getWordDao();
allWordsLive = wordDao.getAllWordsLive();
}
LiveData<List<Word>> getAllWordsLive() {
return allWordsLive;
}
void insertWords(Word... words) {
new InsertAsynceTask(wordDao).execute(words);
}
void updateWords(Word... words) {
new UpdateAsynceTask(wordDao).execute(words);
}
void deleteWords(Word... words) {
new DeleteAsynceTask(wordDao).execute(words);
}
void deleteallWords() {
new DeleteAllAsynceTask(wordDao).execute();
}
static class InsertAsynceTask extends AsyncTask<Word, Void, Void> {
private WordDao wordDao;
InsertAsynceTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Word... words) {
wordDao.insertWord(words);
return null;
}
}
static class UpdateAsynceTask extends AsyncTask<Word, Void, Void> {
private WordDao wordDao;
UpdateAsynceTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Word... words) {
wordDao.updateWord(words);
return null;
}
}
static class DeleteAsynceTask extends AsyncTask<Word, Void, Void> {
private WordDao wordDao;
DeleteAsynceTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Word... words) {
wordDao.deleteWord(words);
return null;
}
}
static class DeleteAllAsynceTask extends AsyncTask<Void, Void, Void> {
private WordDao wordDao;
DeleteAllAsynceTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Void... voids) {
wordDao.deleteALLWord();
return null;
}
}
}
View Code
WordViewModel(页面数据)
package com.example.roombasic;
import android.app.Application;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordViewModel extends AndroidViewModel {
private WordDao wordDao;
private WordRepository wordRepository;
private LiveData<List<Word>> allWordsLive;
public WordViewModel(@NonNull Application application) {
super(application);
wordRepository=new WordRepository(application);
}
LiveData<List<Word>> getAllWordsLive() {
return wordRepository.getAllWordsLive();
}
void insertWords(Word...words){
wordRepository.insertWords(words);
}
void updateWords(Word...words){
wordRepository.updateWords(words);
}
void deleteWords(Word...words){
wordRepository.deleteWords(words);
}
void deleteallWords(){
wordRepository.deleteallWords();
}
}
View Code
MyAdapter(适配器)
package com.example.roombasic;
import android.content.Intent;
import android.net.Uri;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHoder> {
List<Word> allwords=new ArrayList<>();
Boolean aBoolean;
public MyAdapter(Boolean aBoolean) {
this.aBoolean = aBoolean;
}
public void setAllwords(List<Word> allwords) {
this.allwords = allwords;
}
@NonNull
@Override
public MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View item;
if(aBoolean){
item =layoutInflater.inflate(R.layout.cell_card,parent,false);
}else{
item =layoutInflater.inflate(R.layout.cell_normal,parent,false);
}
return new MyViewHoder(item);
//return null;
}
@Override
public void onBindViewHolder(@NonNull final MyViewHoder holder, int position) {
Word word=allwords.get(position);
holder.textViewNumber.setText(String.valueOf(position+1));
holder.textViewEnglish.setText(word.getWord());
holder.textViewChinese.setText(word.getMeaning());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri=Uri.parse("http://m.youdao.com/dict?le=eng&q="+holder.textViewEnglish.getText());
Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
holder.itemView.getContext().startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return allwords.size();
}
static class MyViewHoder extends RecyclerView.ViewHolder{
TextView textViewNumber,textViewEnglish,textViewChinese;
public MyViewHoder(@NonNull View itemView) {
super(itemView);
textViewNumber=itemView.findViewById(R.id.textViewNumber);
textViewChinese=itemView.findViewById(R.id.textViewChinese);
textViewEnglish=itemView.findViewById(R.id.textViewEnglish);
}
}
}
View Code
MainActivity
package com.example.roombasic;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
WordDatabase wordDatabase;
WordDao wordDao;
Button insertbutton,clearbutton;
LiveData<List<Word>>allWordsLive;
WordViewModel wordViewModel;
RecyclerView recyclerView;
Switch aSwitch;
MyAdapter myAdapter1,myAdapter2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wordViewModel= ViewModelProviders.of(this).get(WordViewModel.class);
recyclerView=findViewById(R.id.recycleview);
myAdapter1=new MyAdapter(false);
myAdapter2=new MyAdapter(true);
//加入线性布局
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//默认第一个是适配器为正常格式
recyclerView.setAdapter(myAdapter1);
//控件切换展示的格式
aSwitch=findViewById(R.id.switchButton);
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
recyclerView.setAdapter(myAdapter2);
}else{
recyclerView.setAdapter(myAdapter1);
}
}
});
//监视数据的变化,及时更新
wordViewModel.getAllWordsLive().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(List<Word> words) {
myAdapter1.setAllwords(words);
myAdapter2.setAllwords(words);
myAdapter1.notifyDataSetChanged();
myAdapter2.notifyDataSetChanged();
}
});
insertbutton=findViewById(R.id.addbutton);
clearbutton=findViewById(R.id.clearbutton);
insertbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String []english={
"hello",
"world",
"apple",
"banana",
"pear",
"watermelon"
};
String []chinese={
"你好",
"世界",
"苹果",
"香蕉",
"梨",
"西瓜"
};
//副线程插入
//new InsertAsynceTask(wordDao).execute(w1,w2);
for(int i=0;i<english.length;i++)
wordViewModel.insertWords(new Word(english[i],chinese[i]));
}
});
clearbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wordViewModel.deleteallWords();
}
});
}
}
View Code
页面实现:
卡片布局
点击视图切换后,跟换为正常布局:
点击相应的item,会跳转到有道词典来翻译当前的单词:
例如点击watermelon这个单词后:
就会跳转掉到:
-------------------------------------------------------------------------------------------------------------------------------------------------
明天要做的是:利用今天复习的东西,先实现基础的整体轮廓的布局,再将python爬取的新闻信息做成卡片展示