教程地址:https://www.bilibili.com/video/av65180549

源码地址:https://github.com/longway777/Android-2019-Tutorial-RoomBasic-step-3

RecyclerView 是一个回收视图,当滚动出屏幕外面的内容会自动回收,回收系统资源

相同的内容,支持用不同的样式来呈现!

创建2个 Layout 资源文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"> <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.1" /> <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.85" /> <TextView
android:id="@+id/textViewNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="1" /> <TextView
android:id="@+id/textViewEnglish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/textViewChinese"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintHorizontal_bias="0.1"
app:layout_constraintStart_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="parent" /> <TextView
android:id="@+id/textViewChinese"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/textViewEnglish"
app:layout_constraintTop_toBottomOf="@+id/textViewEnglish" /> <ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_chevron_right_black_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

  

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:orientation="vertical"> <androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="?selectableItemBackground"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"> <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.10948905" /> <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.85" /> <TextView
android:id="@+id/textViewNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="1" /> <TextView
android:id="@+id/textViewEnglish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/textViewChinese"
app:layout_constraintEnd_toStartOf="@+id/guideline5"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guideline4"
app:layout_constraintTop_toTopOf="parent" /> <TextView
android:id="@+id/textViewChinese"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/textViewEnglish"
app:layout_constraintTop_toBottomOf="@+id/textViewEnglish" /> <ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline5"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_chevron_right_black_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>

  

2.创建 适配器 Adapter类 ,继承自  RecylerView.Adapter ,是 RecyclerView 的内容管理器

package com.example.roombasic;

import android.content.Intent;
import android.net.Uri;
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.MyViewHolder> { //用来存放数据的列表
List<Word> allWords = new ArrayList<>();
boolean use_CellCard; //是否使用 cell_card 这个样式 public MyAdapter(boolean use_CellCard) {
this.use_CellCard = use_CellCard;
} public void setAllWords(List<Word> allWords) {
this.allWords = allWords;
} @NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); //用开关控件,控制不同的样式
View itemView ;
if(use_CellCard)
itemView = layoutInflater.inflate(R.layout.cell_card,parent,false);
else
itemView = layoutInflater.inflate(R.layout.cell_normal,parent,false); return new MyViewHolder(itemView);
} //数据绑定
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
//数据绑定
final Word word = allWords.get(position); //通过位置找到内容
holder.textViewNumber.setText(String.valueOf(position + 1));
holder.textViewEnglish.setText(word.getWord());
holder.textViewChinese.setText(word.getChineseMeaning()); 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();
} // 因为需要管理三个内容,左边的数字,右上英文,右下汉字,所以创建三个值来管理
// 创建一个属于 Adapter 自身的 ViewHolder
//加 static 防内存泄漏
static class MyViewHolder extends RecyclerView.ViewHolder{ TextView textViewNumber,textViewEnglish,textViewChinese; public MyViewHolder(@NonNull View itemView) {
super(itemView); textViewNumber = itemView.findViewById(R.id.textViewNumber);
textViewEnglish = itemView.findViewById(R.id.textViewEnglish);
textViewChinese = itemView.findViewById(R.id.textViewChinese);
}
}
}

  

  

3. MainActivity.java 类

package com.example.roombasic;

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 androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class MainActivity extends AppCompatActivity { //WordDatabase wordDatabase;
//WordDao wordDao;
Button buttonInsert,buttonUpdate,buttonClear,buttonDelete;
TextView textView;
LiveData<List<Word>> allWordsLive; WordViewModel wordViewModel; RecyclerView recyclerView;
MyAdapter myAdapter1; //cell_normal
MyAdapter myAdapter2; //cell_card ,这里必须弄2个适配器,要不然一切换数据加载不出来!?? Switch aSwitch; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//wordDatabase = Room.databaseBuilder(this,WordDatabase.class,"word_database")
//.allowMainThreadQueries() //allowMainThreadQueries() 强制允许在主线程运行
// .build(); //wordDao = wordDatabase.getWordDao(); //wordViewModel = ViewModelProviders recyclerView = findViewById(R.id.recyclerView); myAdapter1 = new MyAdapter(false);
myAdapter2 = new MyAdapter(true); recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(myAdapter1); wordViewModel = new ViewModelProvider(this,new SavedStateViewModelFactory(getApplication(),this)).get(WordViewModel.class); //allWordsLive = wordDao.getAllWordLive(); textView = findViewById(R.id.textViewNumber);
buttonInsert = findViewById(R.id.buttonInsert);
buttonUpdate = findViewById(R.id.buttonUpdate);
buttonClear = findViewById(R.id.buttonClear);
buttonDelete = findViewById(R.id.buttonDelete);
aSwitch = findViewById(R.id.switch1); //开关监听,用的是哪种样式?
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(aSwitch.isChecked()){
recyclerView.setAdapter(myAdapter2);
}
else{
recyclerView.setAdapter(myAdapter1);
}
}
}); //利用 LiveData<> 与 observe的onChanged配合,数据自动刷新
//allWordsLive.observe(this, new Observer<List<Word>>() {
wordViewModel.getAllWordsLive().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(List<Word> words) {
//当数据改变时会自动呼叫这个函数
//String text="";
/*StringBuilder text = new StringBuilder();
textView.setText(text); //先将 textView 清空
for(int i=0;i<words.size();i++){
Word word = words.get(i);
text.append(word.getId() + ":" + word.getWord() + "=" + word.getChineseMeaning() + "\n"); textView.setText(text);
}*/ myAdapter1.setAllWords(words);
myAdapter1.notifyDataSetChanged(); myAdapter2.setAllWords(words);
myAdapter2.notifyDataSetChanged();
}
}); buttonInsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { String[] english = new String[]{"Hello",
"World",
"Android",
"Google",
"Studio",
"Project",
"Database",
"RecyclerView",
"View",
"Value"
}; String[] chinese;
chinese = new String[]{"你好",
"世界",
"安卓",
"谷歌",
"工作室",
"项目",
"数据库",
"回收站",
"视图",
"数值"
}; for(int i=0;i<english.length;i++){
wordViewModel.insertWords(new Word(english[i],chinese[i]));
} }
}); buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("English","英语");
word.setId(76); //更新是用主键来更新的
wordViewModel.updateWords(word);
//wordDao.updateWords(word);
//new UpdateAsyncTask(wordDao).execute(word);
//updateView();
}
}); //删除所有的记录
buttonClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//wordDao.deleteAllWords();
//new DeleteAllAsyncTask(wordDao).execute();
//updateView();
wordViewModel.deleteAllWords();
}
}); buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("English","英语");
word.setId(76); //删除也是用主键来更新的
wordViewModel.deleteWords(word);
//wordDao.deleteWords(word);
//new DeleteAsyncTask(wordDao).execute(word);
//updateView();
}
}); } /*void updateView(){
List<Word> list = wordDao.getAllWords();
String text="";
textView.setText(text); //先将 textView 清空
for(int i=0;i<list.size();i++){
Word word = list.get(i);
text += word.getId() + ":" + word.getWord() + "=" + word.getChineseMeaning() + "\n"; textView.setText(text);
}
}*/ }

  

4.细节

项目每一行设置可点击,在cell_normal.xml 中 设置   android:clickable="true"

项目点击后,有一个背景, android:foreground="?selectableItemBackground"

 

最新文章

  1. Win10计算器在哪里?三种可以打开Win10计算器的方法图文介绍
  2. MongoDB的基础知识
  3. 批处理命令——goto 和 :
  4. Protocol Buffer技术详解(C++实例)
  5. Project Euler 110:Diophantine reciprocals II 丢番图倒数II
  6. 配置Apache+Mysql+Php
  7. free 命令解释
  8. HDOJ 2081 手机短号
  9. Linux下那些奇葩的命令
  10. mysql 主从搭建
  11. NSDate显示和时区的关系
  12. 记录下url拼接的多条件筛选js
  13. iOS CGRectContainsPoint的用法
  14. oracle中数字保留几位小数的问题
  15. docker-compose初试及命令基础
  16. 「PKUWC2019」拓扑序计数(状压dp)
  17. 2018-北航-面向对象第三次OO作业分析与小结
  18. ThreadLocal理解
  19. 使用Zend studio+WAMP来调试Wordpress后台的PHP程序的一些非常关键的信息(原创)
  20. icmp隧道手工操作

热门文章

  1. golang ---timeb
  2. IDEA 设置: Live Templates 方法注释 注释模板编写
  3. 微信小程序主要开发语言
  4. c# winform devexpress TreeList过滤和绑定
  5. linux centos无法删除网站根目录下的.user.ini解决办法
  6. LiveBOS Webservice初步使用
  7. Linux磁盘分区(9)
  8. 2019-09-11 redis命令【转载】
  9. FreeMarker学习系列之一
  10. Vue+element 解决浏览器自动填充记住的账号密码问题