第一阶段:冲刺5(android---新闻热搜界面设置)
今天一天都在搞热搜界面,之前学习过android的数据库操作,里面有个界面(下图)和热搜界面很像,都是分成一块一块的。于是今天就试着做了一下。本来想偷懒,复制项目,修改实体类等一些东西,但是最后改的时候改疯了。好多东西都忘了,在加上android的Room坑爹的操作,只要动了,实体类,就得改版本,报一堆乱七八糟的错误。最后我不得不自己重新敲了一遍。
这是我根据qq热搜和微博热搜设计的(忽略那两个键,clear不能用):每一个都是一个小模块
目前只是页面的设计,自己添加东西。以后会实现从数据库里读取内容,然后显示到改页面中。
写这个页面用到的东西还挺多,包括数据库操作,工厂设计,viewModel,和LiveData(没想到一个页面让我弄得这么复杂):
因为有数据库操作,所以得在gradle(Module:app)添加依赖如下:
def room_version = "2.2.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
首先是一个子模块,就是我们每一个小块的内容:
<?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="60dp"
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.80" />
<TextView
android:id="@+id/textViewNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintHorizontal_bias="0.516"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewSearchNum"
android:layout_width="66dp"
android:layout_height="20dp"
android:layout_marginTop="28dp"
android:layout_marginBottom="23dp"
android:text="233w人查询"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.562"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.545" />
<EditText
android:id="@+id/editTextTitle"
android:layout_width="243dp"
android:layout_height="40dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintHorizontal_bias="0.294"
app:layout_constraintStart_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后是我们的主页面:用到了recyclerView
<?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="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline"
app:layout_constraintVertical_bias="1.0" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.15" />
<Button
android:id="@+id/buttonInsert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Insert"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.126"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.58" />
<Button
android:id="@+id/buttonClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="clear"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.826"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.58" />
</androidx.constraintlayout.widget.ConstraintLayout>
新闻实体类:
展开查看
package com.example.hotsearch;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;@Entity
public class New_ {
@PrimaryKey(autoGenerate = true)
private int id;
// @ColumnInfo(name = "评论数量")
private int commentCount;
// @ColumnInfo(name = "阅读量")
private int priority;
// @ColumnInfo(name = "来源")
private String source;
// @ColumnInfo(name = "标题")
private String title;
// @ColumnInfo(name = "摘要")
private String digest;
// @ColumnInfo(name = "图片地址")
private String imgsrc;
// @ColumnInfo(name = "时间")
private String ptime;
// @ColumnInfo(name = "正文")
private String zw;
// @ColumnInfo(name = "类型")
private String type;
private Boolean history = false;public New_(int priority, String title) { this.priority = priority; this.title = title; } public Boolean getHistory() { return history; } public void setHistory(Boolean history) { this.history = history; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getCommentCount() { return commentCount; } public void setCommentCount(int commentCount) { this.commentCount = commentCount; } public int getPriority() { return priority; } public void setPriority(int priority) { this.priority = priority; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDigest() { return digest; } public void setDigest(String digest) { this.digest = digest; } public String getImgsrc() { return imgsrc; } public void setImgsrc(String imgsrc) { this.imgsrc = imgsrc; } public String getPtime() { return ptime; } public void setPtime(String ptime) { this.ptime = ptime; } public String getZw() { return zw; } public void setZw(String zw) { this.zw = zw; } public String getType() { return type; } public void setType(String type) { this.type = type; }
}
数据库操作接口NewsDao
展开查看
package com.example.hotsearch;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;import java.util.List;
@Dao
public interface NewsDao {
@Insert
public void insertNews(New_...new_s);
@Query("SElECT * FROM New_")
public LiveData<List<New_>> getAllNewsLive();
@Query("DELETE FROM New_")
public void deleteAllNews();
}
数据库NewsDataBase
展开查看
package com.example.hotsearch;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {New_.class},version = 1,exportSchema = false)
public abstract class NewsDatabase extends RoomDatabase {
private static NewsDatabase INSTANCE;
static synchronized NewsDatabase getDatabase(Context context){
if(INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),NewsDatabase.class,"new_database")
.allowMainThreadQueries()
.build();
}
return INSTANCE;
}
public abstract NewsDao getNewsDao();
}
工厂NewsRepository
展开查看
package com.example.hotsearch;
import android.content.Context;
import android.os.AsyncTask;import androidx.lifecycle.LiveData;
import java.util.List;
public class NewsRepository {
private LiveData<List<New_>> allNews;
private NewsDao newsDao;
public NewsRepository(Context context) {
NewsDatabase wordDatabase = NewsDatabase.getDatabase(context.getApplicationContext());
newsDao = wordDatabase.getNewsDao();
allNews = newsDao.getAllNewsLive();
}public LiveData<List<New_>> getAllNews() { return allNews; } // 定义类的接口-- 插入 public void insertNews(New_...news){ new InsertAsyncTask(newsDao).execute(news); } // 插入类 static class InsertAsyncTask extends AsyncTask<New_,Void,Void> { private NewsDao newsDao; public InsertAsyncTask(NewsDao newsDao) { this.newsDao = newsDao; } // 将在主线程的工作放到后台来执行 @Override protected Void doInBackground(New_...new_s) { newsDao.insertNews(new_s); return null; } }
}
NewViewModel
展开查看
package com.example.hotsearch;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;import java.util.List;
public class NewsViewModel extends AndroidViewModel {
private NewsRepository newsRepository;
public NewsViewModel(@NonNull Application application) {
super(application);
newsRepository = new NewsRepository(application);
}public LiveData<List<New_>> getAllNews() { return newsRepository.getAllNews(); } // 定义类的接口-- 插入 public void insertWords(New_...news){ newsRepository.insertNews(news); }
}
适配器MyAdapter
展开查看
package com.example.hotsearch;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
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<New_> allNews = new ArrayList<>();public void setAllNews(List<New_> allNews) { this.allNews = allNews; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); View itemViem = layoutInflater.inflate(R.layout.cell_normal, parent,false); return new MyViewHolder(itemViem); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { New_ new_ = allNews.get(position); holder.textViewNumber.setText(String.valueOf(position)); holder.editTextTitle.setText(new_.getTitle()); holder.textViewSearchNum.setText(new_.getPriority()+"人查询"); } @Override public int getItemCount() { return allNews.size(); } //用来管理我们新建的ConstraintLayout static class MyViewHolder extends RecyclerView.ViewHolder { TextView textViewNumber,textViewSearchNum; EditText editTextTitle; public MyViewHolder(@NonNull View itemView) { super(itemView); textViewNumber = itemView.findViewById(R.id.textViewNumber); editTextTitle = itemView.findViewById(R.id.editTextTitle); textViewSearchNum = itemView.findViewById(R.id.textViewSearchNum); } }
}
MainActivity
展开查看
package com.example.hotsearch;
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 androidx.room.Room;import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;import java.util.List;
public class MainActivity extends AppCompatActivity {
Button buttonInsert,buttonClear;
NewsViewModel newsViewModel;
RecyclerView recyclerView;
MyAdapter myAdapter;@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonInsert = findViewById(R.id.buttonInsert); buttonClear = findViewById(R.id.buttonClear); recyclerView = findViewById(R.id.RecyclerView); myAdapter = new MyAdapter(); newsViewModel = ViewModelProviders.of(this).get(NewsViewModel.class); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(myAdapter); newsViewModel.getAllNews().observe(this, new Observer<List<New_>>() { @Override public void onChanged(List<New_> new_s) { myAdapter.setAllNews(new_s); myAdapter.notifyDataSetChanged(); } }); buttonInsert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { New_ new_2 = new New_(400,"aaa"); newsViewModel.insertWords(new_2); } }); }
}