RecyclerView+SearchView (简单实现)
简述: 简单实现点赞计数功能,按照个人想法实现文本检索功能,针对界面进行了美化。 (个人理解,有误指出)
检索功能实现思路:
控件导入:直接引入官方自带的SearchView控件,期间也是深受版本问题的困扰,如果导入控件使用androidx.appcompat.widget.SearchView报错,可以换成SearchView,(建议还是使用GUI界面拖动,版本问题是个诟病) 建议自己实现EditText。
简单思路:
(1)SearchView自带搜索图标和删除键,直接引入控件即可
(2) 实现搜索列表的即时显示,我们可以想一下,显示列表是根据数据创建一个adapter并设置显示,那么我们可以找到我们需要的数据,加入对应的List之中创建一个搜索结果的adapter,这样就能达到显示搜索结果的目的,即时性的实现采用监听器之中实现的onQueryTextChange方法,每搜索框改变一个字符便会回调该方法,每次调用该方法我们就创建一个新的adapter更新数据。
(3) 搜索文本匹配可以采用模拟匹配(小文本)或者 正则表达式匹配,但是两者的匹配标准不同(之后具体实现会提到) 。
(3) 每次找到对应的新数据之前先把原来储存用的LIst清空。
具体实现:
(1) 匹配所有的标签是否含有检索文本(搜索框的输入),我这里的子串的定义就是,按照先后顺序去掉若干个能得到目标串,这个串就称之为父串。比如:好久不见。 我们可以认定为是 “好不”的父串 ,简单来说,只要是按照顺序,能够找出每一个字符,我们就称之为父串。 实现方法:简单的正则表达式匹配 , 将输入的字符串拆分成单个字符 ,转化为正则表达式
诸如 : 字符1{1} + "[sS]" + 字符2{1} ,字符1{1} 代表字符1出现一次,"[sS]"代表匹配所有的字符(空或者非空)
这样的实现实际上就是为了贴合我们上面所说的子串理论,只要按照顺序出现一个字符1 。。。。。 字符2即可,中间出现的字符我们可以默认为任意,这样就可以用正则表达式完成文本匹配。
(2) 匹配的第二种实现,简单的模拟即可(实际上可以来个kmp),把搜索框的字符串进行拆分,去每一个标签之中寻找,每次都标记当前标签之中出现过的搜索框字符(bool数组标记即可),这样的匹配只要求出现过搜索框之中的所有字符就是合法的。 例子: 搜索框输入AS,对应的ASR在第一二种方法之中都会被匹配到 ,但是输入SA,只有第二种之中才会匹配到ASR。
不足 :按照个人理解实现的检索功能,效率过低,文本匹配的模式单一,而且无法实现光亮操作。
点赞计数实现
实现方法1. 采用图片切换的方法,首先获取一系列带数字的图片的id,设置一个计数器,然后将获取的id组成一个数组,针对对应计数器设置对应id的图片。
实现方法2. 相应的弄一个TextView,设置对应的监听器,点击一次计数器加一,设置的文本+1
(两种方法,方法二渲染时间少,占用空间少)
效果图:
(1) 正则表达式匹配 + 文本框进行更新计数
(2) 正则表达式匹配 + 图片切换计数
(3) 模拟匹配 + 图片切换计数
(4) 模拟匹配 + 文本框进行更新计数
框架图
采用的javaBean
package com.example.logindemo;
public class AlbumInfo {
public String title;
public String info;
public int imageId;
public AlbumInfo(String title, String info, int imageId) {
this.title = title;
this.info = info;
this.imageId = imageId;
}
public String getTitle() {
return title;
}
public String getInfo() {
return info;
}
public int getImageId() {
return imageId;
}
}
Recycler_View.java (方法一,模拟实现)
package com.example.logindemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Recycler_View extends AppCompatActivity {
private List<AlbumInfo> mData = new ArrayList<>();
/// 储存原始的总数据
private List<AlbumInfo> search_mData = new ArrayList<>();
/// 搜索之后的更新数据
private SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
getData();// 获取数据
searchView = findViewById(R.id.search) ;
RecyclerView recycleView = (RecyclerView)findViewById(R.id.babyAlbumlist);
// 获取组件
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycleView.setLayoutManager(layoutManager);
// 设置线性布局
AlbumAdapter adapter = new AlbumAdapter(mData);
recycleView.setAdapter(adapter);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// 当搜索框内容变化 , 新的搜索数据清除,并更新
search_mData.clear();
find(newText);
AlbumAdapter adapter = new AlbumAdapter(search_mData);
/// 新的adapter进行数据更新
recycleView.setAdapter(adapter);
return false;
}
});
}
private boolean check(String a,String b)
{
int vis[] = new int[1000];//标记位置
/// a 搜索框字符串 b标签字符串
for (int i=0;i<a.length();++i)
{
char x = a.charAt(i);
boolean flag = false;
for (int j=0;j<b.length();++j)
{
char y = b.charAt(j);
// 如果在标签之中该字符出现过,直接标记
if(vis[j]==0 && x==y)
{
vis[j]=1;
flag = true;
break;
}
}
/// 未找到未标记的,说明不是合法的匹配
if (!flag) return false;
}
return true;
}
private void find(String x)
{
for (int i=0;i<mData.size();++i)
{
if (check(x,mData.get(i).title))
{
search_mData.add(mData.get(i));
/// 找到的新的,作为更新
}
}
}
private void getData()
{
AlbumInfo albumInfo = new AlbumInfo("DX-巭 A","悬浮核心科技带来突破性操控体验,手柄前端释放,球路更开阔。动力流体六角框搭配百洛碳纤维中管,刚柔相济,攻守圆通,全面操控。更适合把握节奏的控制型选手。",R.drawable.i1);
mData.add(albumInfo);
AlbumInfo albumInfo2 = new AlbumInfo("TK-7U F","轻量+30lbs高磅,挥拍轻松更好上手,适合喜欢轻量打感的进攻型球友。",R.drawable.i2);
mData.add(albumInfo2);
AlbumInfo albumInfo3 = new AlbumInfo("BRS-11R D","经典手感的继承,菱形破风框的升华,再现速度与操控的优异平衡。",R.drawable.i3);
mData.add(albumInfo3);
AlbumInfo albumInfo4 = new AlbumInfo("DX-9X B","动力流体六角框结合轻量化硬中管,挥拍出球自如舒畅,打在悬浮核心科技(FREE CORE)手柄,带来突破性操控体验,更适合控制型打法的选手",R.drawable.i4);
mData.add(albumInfo4);
AlbumInfo albumInfo5 = new AlbumInfo("JS-12F J ","JS-12的好拍档,外表清新,内在灵活,速攻致胜!具有轻快的手感及良好的舒适性,让你的击球瞬间更具有爆发力。",R.drawable.i5);
mData.add(albumInfo5);
AlbumInfo albumInfo6 = new AlbumInfo("ARS-70K F","新的回弹技术实现力量与速度并存的理想,挑战速度拍的新高度,适合节奏多变的双打选手及防守反击的单打选手。",R.drawable.i6);
mData.add(albumInfo6);
AlbumInfo albumInfo7 = new AlbumInfo("TK-F C A","小平头与72孔精确扎实的利爪设定,进阶导入PYROFIL及弹力盾科技,搭配锐白涂装,体现稳狠准的进攻美学。",R.drawable.i7);
mData.add(albumInfo7);
AlbumInfo albumInfo8 = new AlbumInfo("TK-F C LTD GB A","戴资颖签名球拍,印有戴爸亲笔提字『相信自己』刺青,代表性的小平头与72孔精确扎实设定,搭配FREE CORE悬浮核心科技人造柄,展现快狠准的进攻美学。戴资颖签名球拍,印有戴爸亲笔提字『相信自己』刺青,代表性的小平头与72孔精确扎实设定,搭配FREE CORE悬浮核心科技人造柄,展现快狠准的进攻美学。",R.drawable.i8);
mData.add(albumInfo8);
AlbumInfo albumInfo9 = new AlbumInfo("DX-8K F","全面偏进攻型球拍,搭载高韧动力纤维,可提高球拍的减震性能,击球时让手感更加扎实。",R.drawable.i9);
mData.add(albumInfo9);
AlbumInfo albumInfo10 = new AlbumInfo("TK-烎 F","易攻迅捷,拍拍精准,适合主动进击的球友使用。",R.drawable.i10);
mData.add(albumInfo10);
AlbumInfo albumInfo11 = new AlbumInfo("JS-2SP C","JS-12的中级拍,保留了强芯填充技术的稳定手感及球拍轻量化的特点,适合能轻松快速上手的羽球爱好者。",R.drawable.i11);
mData.add(albumInfo11);
AlbumInfo albumInfo12 = new AlbumInfo("DX-巭 A","悬浮核心科技带来突破性操控体验,手柄前端释放,球路更开阔。动力流体六角框搭配百洛碳纤维中管,刚柔相济,攻守圆通,全面操控。更适合把握节奏的控制型选手。",R.drawable.i1);
mData.add(albumInfo12);
AlbumInfo albumInfo13 = new AlbumInfo("TK-7U F","轻量+30lbs高磅,挥拍轻松更好上手,适合喜欢轻量打感的进攻型球友。",R.drawable.i2);
mData.add(albumInfo13);
AlbumInfo albumInfo14 = new AlbumInfo("BRS-11R D","经典手感的继承,菱形破风框的升华,再现速度与操控的优异平衡。",R.drawable.i3);
mData.add(albumInfo14);
AlbumInfo albumInfo15 = new AlbumInfo("DX-9X B","动力流体六角框结合轻量化硬中管,挥拍出球自如舒畅,打在悬浮核心科技(FREE CORE)手柄,带来突破性操控体验,更适合控制型打法的选手",R.drawable.i4);
mData.add(albumInfo15);
AlbumInfo albumInfo16 = new AlbumInfo("JS-12F J ","JS-12的好拍档,外表清新,内在灵活,速攻致胜!具有轻快的手感及良好的舒适性,让你的击球瞬间更具有爆发力。",R.drawable.i5);
mData.add(albumInfo16);
AlbumInfo albumInfo17 = new AlbumInfo("ARS-70K F","新的回弹技术实现力量与速度并存的理想,挑战速度拍的新高度,适合节奏多变的双打选手及防守反击的单打选手。",R.drawable.i6);
mData.add(albumInfo17);
AlbumInfo albumInfo18 = new AlbumInfo("TK-F C A","小平头与72孔精确扎实的利爪设定,进阶导入PYROFIL及弹力盾科技,搭配锐白涂装,体现稳狠准的进攻美学。",R.drawable.i7);
mData.add(albumInfo18);
AlbumInfo albumInfo19 = new AlbumInfo("TK-F C LTD GB A","戴资颖签名球拍,印有戴爸亲笔提字『相信自己』刺青,代表性的小平头与72孔精确扎实设定,搭配FREE CORE悬浮核心科技人造柄,展现快狠准的进攻美学。戴资颖签名球拍,印有戴爸亲笔提字『相信自己』刺青,代表性的小平头与72孔精确扎实设定,搭配FREE CORE悬浮核心科技人造柄,展现快狠准的进攻美学。",R.drawable.i8);
mData.add(albumInfo19);
AlbumInfo albumInfo20 = new AlbumInfo("DX-8K F","全面偏进攻型球拍,搭载高韧动力纤维,可提高球拍的减震性能,击球时让手感更加扎实。",R.drawable.i9);
mData.add(albumInfo20);
AlbumInfo albumInfo21 = new AlbumInfo("TK-烎 F","易攻迅捷,拍拍精准,适合主动进击的球友使用。",R.drawable.i10);
mData.add(albumInfo21);
AlbumInfo albumInfo22 = new AlbumInfo("JS-2SP C","JS-12的中级拍,保留了强芯填充技术的稳定手感及球拍轻量化的特点,适合能轻松快速上手的羽球爱好者。",R.drawable.i11);
mData.add(albumInfo22);
}
}
Recycler_View.java (方法二,正则表达式实现)
private boolean check(String a,String b) {
/// 这个是唯一要改的方法
String regEx = new StringBuilder().append("").toString();
/// 将搜索框的字符按照 字符1{1}[\s\S]*字符2{1}[\s\S]*字符3{1}..... 进行连接
int l = a.length();
for (int i=0;i<l;++i)
{
if (i==0)
{
regEx += a.charAt(i)+"{1}";
continue;
}
regEx += "[\s\S]*"+a.charAt(i)+"{1}";
}
// System.out.println(regEx);
Pattern p;
Matcher m;
p = Pattern.compile(regEx);
System.out.println(p);
m = p.matcher(b);
System.out.println(m);
/// 执行正则化 部分匹配
if (m.find()) {
return true;
} else {
return false;
}
}
AlbumAdapter.java (计数采用TextView)
package com.example.logindemo;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {
private List<AlbumInfo> albumInfoList;
private int cnt[] = new int[100];
int pic[] = new int[]{R.drawable.text0,R.drawable.text1, R.drawable.text2, R.drawable.text3};
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView album_thumb;
TextView album_title;
TextView album_info;
TextView album_btn;
public ViewHolder(@NonNull View itemView) {
super(itemView);
this.album_thumb = (ImageView)itemView.findViewById(R.id.album_thumb);
this.album_title = (TextView)itemView.findViewById(R.id.album_title);
this.album_info = (TextView)itemView.findViewById(R.id.album_info);
this.album_btn = (TextView) itemView.findViewById(R.id.btn);
/// 获取id
}
}
public AlbumAdapter(List<AlbumInfo> albumInfoList) {
this.albumInfoList = albumInfoList;
/// 构造函数
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
AlbumInfo album = albumInfoList.get(position);
holder.album_thumb.setImageResource(album.getImageId());
holder.album_title.setText(album.getTitle());
holder.album_info.setText(album.getInfo());
/// 数据填充
Log.e("AlbumAdapter","onBindViewHolder"+position);
}
@Override
public int getItemCount() {
return albumInfoList.size();
}
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_bt,parent,false);
final ViewHolder holder = new ViewHolder(view);
Log.e("AlbumAdapter","onCreateViewHolder");
/// 设置监听
holder.album_thumb.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int position = holder.getAdapterPosition();
AlbumInfo data = albumInfoList.get(position);
Toast.makeText(v.getContext(),data.getTitle()+"image",Toast.LENGTH_SHORT).show();
}
});
holder.album_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
int position = holder.getAdapterPosition();
showInfo(position,v.getContext());
/// 对应位置的计数器加一
cnt[position] += 1;
/// 对应的text数值设置为+1
holder.album_btn.setText(cnt[position]+"");
}
});
return holder;
}
private void showInfo(int position, Context context)
{
AlbumInfo data = albumInfoList.get(position);
new AlertDialog.Builder(context)
.setTitle(data.getTitle())
.setMessage(data.getInfo())
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
activity_recycler_view.xml
<?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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.appcompat.widget.SearchView
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="true"
android:background="@drawable/round_shape"
android:queryHint="请输入搜索内容" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/babyAlbumlist"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
card_view_bt.xml (此时计数采用TextView显示)
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="5dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/round_shape"
android:padding="5dp">
<ImageView
android:id="@+id/album_thumb"
android:layout_width="0dp"
android:layout_height="137dp"
android:layout_margin="5dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/album_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
<TextView
android:id="@+id/album_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp" />
<TextView
android:id="@+id/btn"
android:layout_width="106dp"
android:layout_height="104dp"
android:layout_gravity="end"
android:layout_marginEnd="10dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:text="0"
android:textSize="40sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
card_view_bt.xml (此时计数采用ImageButton显示)
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="5dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/round_shape"
android:padding="5dp">
<ImageView
android:id="@+id/album_thumb"
android:layout_width="0dp"
android:layout_height="137dp"
android:layout_margin="5dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/album_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
<TextView
android:id="@+id/album_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp" />
<ImageButton
android:id="@+id/album_btn"
android:layout_width="61dp"
android:layout_height="104dp"
android:layout_gravity="end"
android:layout_marginEnd="10dp"
android:layout_marginBottom="5dp"
android:background="@android:color/transparent"
android:src="@drawable/text0" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>