zoukankan      html  css  js  c++  java
  • Android Studio 之 ROM【3】,LiveData+ViewModel+AsyncTask+Repository+RecyclerView

    教程地址: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() + "
    ");
    
                        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() + "
    ";
    
                textView.setText(text);
            }
        }*/
    
    
    
    
    }
    

      

     4.细节

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

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

     
  • 相关阅读:
    JS标签获取另一个页面传过来的href值
    jsp/servlet实现简单上传和下载
    servlet跳转页面后图片不显示
    Nginx 配置实例-动静分离
    将博客搬至博客园
    nginx 配置实例-反向代理
    Nginx 简介与安装、常用的命令和配置文件
    nginx 配置实例-负载均衡
    nginx 配置实例-反向代理
    Nginx 简介与安装、常用的命令和配置文件
  • 原文地址:https://www.cnblogs.com/gfwei/p/11817003.html
Copyright © 2011-2022 走看看