功能介绍:
- 效果视频:
- 在list view中添加Cardview实现滚动的效果;
- 点击收藏按钮,收藏按钮会变为红色(后续添加收藏此工具)
- 收藏按钮和card view的点击事件分开。
- 图片通过Url加载网络图片
重难点梳理:
关于listview适配器Adapter
如上图所示,新建一个文件写我们的适配器。
在别的文件中使用我自己Adapter怎么传递参数进来
public class ToolsCardListAdapter extends BaseAdapter {
String TAG = "ToolsCardListAdapter";
LayoutInflater inflater; //作用相当于FindViewById,反射器
List<Map<String, Object>> list;
public ToolsCardListAdapter(LayoutInflater flater) {
inflater = flater;
}
写一个方法名和你的类名一样的函数,并设置参数 ,这样在别的文件中调用的时候就可以传递你需要的的参数进来,我这里的listview是写在fragment中所以需要传递flater进来,去获取Fragment中的一些资源。
在Fragment中的调用:
ToolsCardListAdapter adapter = new ToolsCardListAdapter(inflater);
怎么通过Adapter把我在xml中写的相关的view加进去
通过重写getView()方法(这里是还没有优化的方法):
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
@SuppressLint("ViewHolder")
View view = inflater.inflate(R.layout.my_card_view,null);
ImageView imageView = view.findViewById(R.id.card_image);
Log.i(TAG, String.format("getView: %s",position));
//Uri uri = Uri.parse((String) list.get(position).get("url"));
Glide.with(imageView).load(list.get(position).get("url")).into(imageView);
//imageView.setImageURI(uri);
TextView title = view.findViewById(R.id.card_title);
TextView text = view.findViewById(R.id.card_text);
title.setText(list.get(position).get("title").toString());
text.setText(list.get(position).get("text").toString());
Log.i(TAG, String.format("getView: %s",position));
return view;
}
这里的cardview是单独写在一个xml文件中,id为my_card_view,这里找到他并且对里里面的控件进行设置,可以看到在这里我将list中的数据添加到相应的Ui中。
注意,这里的参数,名字随便起,第一个是位置默认有可能是i,第二个是可以复用的view,第三个我没用的,我也不知道,你知道的话欢迎评论区留言。
那么list中的数据又是怎么传递进来的呢?
怎么将需要的数据传递进来
当然是写个方法传递进来啦!
public void setList(List<Map<String, Object>> list1){
Log.i(TAG, String.format("setList: %s",list1));
list = list1;
}
在fragment中装填数据:
String[] urls = new String[]{"https://fanyi-cdn.cdn.bcebos.com/static/translation/img/header/logo_e835568.png",
"https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/55540c3d94454de0a7492fbf13569a96.png",
"https://img-home.csdnimg.cn/images/20201124032511.png",
"https://img-home.csdnimg.cn/images/20201124032511.png"};
String[] titles = new String[]{"查单词","查音标","去CSDN","去CSDN"};
String[] texts = new String[]{"源自百度翻译Api","算了,随便写算了","去CSDN,给勇敢di牛牛点赞","去CSDN,看勇敢di牛牛有没有发布新文章"};
//装填数据
for (int i =0;i < urls.length;i++){
Map<String,Object> map = new HashMap<String,Object>();
map.put("url",urls[i]);
map.put("title",titles[i]);
map.put("text",texts[i]);
list.add(map);
}
ToolsCardListAdapter adapter = new ToolsCardListAdapter(inflater);
listView = binding.toollist;
adapter.setList(list);
关于点击事件的添加:
怎么给item添加点击事件,并且确定点的是哪一个:
在Fragment文件中setOnItemClickListener重写这个方法:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Log.i(TAG, String.format("onItemClick: listviewItem 点击事件生效:第 %s 个!",position));
Toast toast = Toast.makeText(getContext(),String.format("你点击的是第 %d 个Item",position),Toast.LENGTH_SHORT);
toast.show();
}
}
);
这里的position 会告诉你是哪一个,同理这个参数由位置决定。
怎么给cardview中的按钮添加点击事件,并且知道是哪一个
在adapter文件中的getview方法中添加点击事件:
imgButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
imgButton.setImageResource(ic_collected);
Log.i(TAG, "onClick: 你点击了收藏按钮!");
Toast toast = Toast.makeText(inflater.getContext(), String.format("你点击的是第 %d 个收藏按钮", position), Toast.LENGTH_SHORT);
toast.show();
}
});
itemview点击事件不生效怎么办:
看我的另一篇文章
【bug记录】关于listview的setOnItemClickListener点击事件不生效。_勇敢di牛牛的博客-CSDN博客关于listview的setOnItemClickListener点击事件不生效。https://blog.csdn.net/niuguobao/article/details/124463708?spm=1001.2014.3001.5501
关于加载网络图片
Glide.with(imageView).load(list.get(position).get("url")).into(imageView);
我这里用的是这个模块,网上都说这好,不知道怎么导入的自行百度。(其实我忘记自己怎么导入这个模块了)
关于布局
每个Itemview之间的间距:
<ListView
android:divider="#00000000"
android:dividerHeight="18dp"
这里的颜色就是透明啥也没有,你可以尝试添加分割线啥的。
其他:
card 根布局中的
android:layout_margin="10dp"
添加到listview之后这个属性是不会生效的。2,
listview中使用
android:layout_margin="20dp"
会连同背景一起延申,显得更加肥大
不会出现间隔的效果。3,
android:layout_height="120dp"指定cardview中的高度,卡片高度才会被修改。
Adapter的优化
其实就是加一个判断:
if (convertView == null) {
//执行上面的操作
return view
}else{
return convertView; //进行布局复用
}
上个两种情况下多次滑动列表的日志就一目了然了:
未优化:
优化后:
上面是划了很多下哦。 是不是节省了很多性能。
上代码
my_card_view.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/transparent_1"
app:cardCornerRadius="14dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:descendantFocusability="blocksDescendants"
android:layout_width="match_parent"
android:layout_height="130dp">
<ImageView
android:id="@+id/card_image"
android:layout_width="120dp"
android:layout_height="140dp"
android:layout_margin="5dp"
android:scaleType="fitCenter"
android:src="@drawable/translate" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/card_collect"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:background="@color/transparent"
android:contentDescription="@string/collect"
android:scaleType="centerCrop"
android:src="@drawable/ic_collect" />
</RelativeLayout>
<TextView
android:id="@+id/card_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/card_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
fragment_tools.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:background="#2F00BCD4"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.tools.ToolsFragment">
<ListView
android:divider="#00000000"
android:dividerHeight="18dp"
android:id="@+id/toollist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp">
</ListView>
</RelativeLayout>
ToolsFragment.java
package com.example.testapp.ui.tools;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.testapp.Util.ToolsCardListAdapter;
import com.example.testapp.databinding.FragmentToolsBinding;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ToolsFragment extends Fragment {
private String TAG = "ToolsFragment";
private ListView listView;
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
private FragmentToolsBinding binding;
@SuppressLint("ResourceType")
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentToolsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
String[] urls = new String[]{"https://fanyi-cdn.cdn.bcebos.com/static/translation/img/header/logo_e835568.png",
"https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/55540c3d94454de0a7492fbf13569a96.png",
"https://img-home.csdnimg.cn/images/20201124032511.png",
"https://img-home.csdnimg.cn/images/20201124032511.png"};
String[] titles = new String[]{"查单词","查音标","去CSDN","去CSDN"};
String[] texts = new String[]{"源自百度翻译Api","算了,随便写算了","去CSDN,给勇敢di牛牛点赞","去CSDN,看勇敢di牛牛有没有发布新文章"};
//装填数据
for (int i =0;i < urls.length;i++){
Map<String,Object> map = new HashMap<String,Object>();
map.put("url",urls[i]);
map.put("title",titles[i]);
map.put("text",texts[i]);
list.add(map);
}
ToolsCardListAdapter adapter = new ToolsCardListAdapter(inflater);
listView = binding.toollist;
adapter.setList(list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Log.i(TAG, String.format("onItemClick: listviewItem 点击事件生效:第 %s 个!",position));
Toast toast = Toast.makeText(getContext(),String.format("你点击的是第 %d 个Item",position),Toast.LENGTH_SHORT);
toast.show();
}
}
);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
ToolsCardListAdapter.java
package com.example.testapp.Util;
import static com.example.testapp.R.drawable.ic_collected;
import android.annotation.SuppressLint;
import android.content.Context;
import java.net.MalformedURLException;
import java.net.URL;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.bumptech.glide.Glide;
import com.example.testapp.R;
import com.example.testapp.ui.tools.ToolsFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
public class ToolsCardListAdapter extends BaseAdapter {
String TAG = "ToolsCardListAdapter";
LayoutInflater inflater; //作用相当于FindViewById,反射器
List<Map<String, Object>> list;
public ToolsCardListAdapter(LayoutInflater flater) {
inflater = flater;
}
public void setList(List<Map<String, Object>> list1){
Log.i(TAG, String.format("setList: %s",list1));
list = list1;
}
@Override
public int getCount() {
return list.toArray().length;
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
View view = inflater.inflate(R.layout.my_card_view, null);
ImageView imageView = view.findViewById(R.id.card_image);
ImageButton imgButton = view.findViewById(R.id.card_collect);
Log.i(TAG, String.format("getView:创建视图,位置: %s", position));
imgButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
imgButton.setImageResource(ic_collected);
Log.i(TAG, "onClick: 你点击了收藏按钮!");
Toast toast = Toast.makeText(inflater.getContext(), String.format("你点击的是第 %d 个收藏按钮", position), Toast.LENGTH_SHORT);
toast.show();
}
});
//Uri uri = Uri.parse((String) list.get(position).get("url"));
Glide.with(imageView).load(list.get(position).get("url")).into(imageView);
//imageView.setImageURI(uri);
TextView title = view.findViewById(R.id.card_title);
TextView text = view.findViewById(R.id.card_text);
title.setText(list.get(position).get("title").toString());
text.setText(list.get(position).get("text").toString());
return view;
}else{
return convertView;
}
}
}
补充
- 代码有点多,请您见谅,下次我会将项目上传到git。
- 有啥疑问可以评论区留言或私信。(一定会回)
- 项目是连贯的,缺的代码在专栏中可以找到。
版权归原作者 勇敢di牛牛 所有, 如有侵权,请联系我们删除。