0


【php + MySQL + Android】在Fragment中实现listview中嵌套cardview

功能介绍:

  • 效果视频:

  • 在list view中添加Cardview实现滚动的效果;
  • 点击收藏按钮,收藏按钮会变为红色(后续添加收藏此工具)
  • 收藏按钮和card view的点击事件分开。
  • 图片通过Url加载网络图片

重难点梳理:

  • 关于listview适配器Adapter

如上图所示,新建一个文件写我们的适配器。

  • 在别的文件中使用我自己Adapter怎么传递参数进来

  1. public class ToolsCardListAdapter extends BaseAdapter {
  2. String TAG = "ToolsCardListAdapter";
  3. LayoutInflater inflater; //作用相当于FindViewById,反射器
  4. List<Map<String, Object>> list;
  5. public ToolsCardListAdapter(LayoutInflater flater) {
  6. inflater = flater;
  7. }

写一个方法名和你的类名一样的函数,并设置参数 ,这样在别的文件中调用的时候就可以传递你需要的的参数进来,我这里的listview是写在fragment中所以需要传递flater进来,去获取Fragment中的一些资源。

在Fragment中的调用:

  1. ToolsCardListAdapter adapter = new ToolsCardListAdapter(inflater);
  • 怎么通过Adapter把我在xml中写的相关的view加进去

通过重写getView()方法(这里是还没有优化的方法):

  1. @Override
  2. public View getView(int position, View convertView, ViewGroup viewGroup) {
  3. @SuppressLint("ViewHolder")
  4. View view = inflater.inflate(R.layout.my_card_view,null);
  5. ImageView imageView = view.findViewById(R.id.card_image);
  6. Log.i(TAG, String.format("getView: %s",position));
  7. //Uri uri = Uri.parse((String) list.get(position).get("url"));
  8. Glide.with(imageView).load(list.get(position).get("url")).into(imageView);
  9. //imageView.setImageURI(uri);
  10. TextView title = view.findViewById(R.id.card_title);
  11. TextView text = view.findViewById(R.id.card_text);
  12. title.setText(list.get(position).get("title").toString());
  13. text.setText(list.get(position).get("text").toString());
  14. Log.i(TAG, String.format("getView: %s",position));
  15. return view;
  16. }

这里的cardview是单独写在一个xml文件中,id为my_card_view,这里找到他并且对里里面的控件进行设置,可以看到在这里我将list中的数据添加到相应的Ui中。

注意,这里的参数,名字随便起,第一个是位置默认有可能是i,第二个是可以复用的view,第三个我没用的,我也不知道,你知道的话欢迎评论区留言。

那么list中的数据又是怎么传递进来的呢?

  • 怎么将需要的数据传递进来

当然是写个方法传递进来啦!

  1. public void setList(List<Map<String, Object>> list1){
  2. Log.i(TAG, String.format("setList: %s",list1));
  3. list = list1;
  4. }

在fragment中装填数据:

  1. String[] urls = new String[]{"https://fanyi-cdn.cdn.bcebos.com/static/translation/img/header/logo_e835568.png",
  2. "https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/55540c3d94454de0a7492fbf13569a96.png",
  3. "https://img-home.csdnimg.cn/images/20201124032511.png",
  4. "https://img-home.csdnimg.cn/images/20201124032511.png"};
  5. String[] titles = new String[]{"查单词","查音标","去CSDN","去CSDN"};
  6. String[] texts = new String[]{"源自百度翻译Api","算了,随便写算了","去CSDN,给勇敢di牛牛点赞","去CSDN,看勇敢di牛牛有没有发布新文章"};
  7. //装填数据
  8. for (int i =0;i < urls.length;i++){
  9. Map<String,Object> map = new HashMap<String,Object>();
  10. map.put("url",urls[i]);
  11. map.put("title",titles[i]);
  12. map.put("text",texts[i]);
  13. list.add(map);
  14. }
  15. ToolsCardListAdapter adapter = new ToolsCardListAdapter(inflater);
  16. listView = binding.toollist;
  17. adapter.setList(list);
  • 关于点击事件的添加:

  • 怎么给item添加点击事件,并且确定点的是哪一个:

在Fragment文件中setOnItemClickListener重写这个方法:

  1. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  2. @Override
  3. public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
  4. Log.i(TAG, String.format("onItemClick: listviewItem 点击事件生效:第 %s 个!",position));
  5. Toast toast = Toast.makeText(getContext(),String.format("你点击的是第 %d 个Item",position),Toast.LENGTH_SHORT);
  6. toast.show();
  7. }
  8. }
  9. );

这里的position 会告诉你是哪一个,同理这个参数由位置决定。

  • 怎么给cardview中的按钮添加点击事件,并且知道是哪一个

在adapter文件中的getview方法中添加点击事件:

  1. imgButton.setOnClickListener(new View.OnClickListener() {
  2. @Override
  3. public void onClick(View view) {
  4. imgButton.setImageResource(ic_collected);
  5. Log.i(TAG, "onClick: 你点击了收藏按钮!");
  6. Toast toast = Toast.makeText(inflater.getContext(), String.format("你点击的是第 %d 个收藏按钮", position), Toast.LENGTH_SHORT);
  7. toast.show();
  8. }
  9. });
  • itemview点击事件不生效怎么办:

看我的另一篇文章

【bug记录】关于listview的setOnItemClickListener点击事件不生效。_勇敢di牛牛的博客-CSDN博客关于listview的setOnItemClickListener点击事件不生效。https://blog.csdn.net/niuguobao/article/details/124463708?spm=1001.2014.3001.5501

  • 关于加载网络图片

  1. Glide.with(imageView).load(list.get(position).get("url")).into(imageView);

我这里用的是这个模块,网上都说这好,不知道怎么导入的自行百度。(其实我忘记自己怎么导入这个模块了)

  • 关于布局

  • 每个Itemview之间的间距:

  1. <ListView
  2. android:divider="#00000000"
  3. android:dividerHeight="18dp"

这里的颜色就是透明啥也没有,你可以尝试添加分割线啥的。

  • 其他:

card 根布局中的
android:layout_margin="10dp"
添加到listview之后这个属性是不会生效的。

2,
listview中使用
android:layout_margin="20dp"
会连同背景一起延申,显得更加肥大
不会出现间隔的效果。

3,

android:layout_height="120dp"指定cardview中的高度,卡片高度才会被修改。

  • Adapter的优化

其实就是加一个判断:

  1. if (convertView == null) {
  2. //执行上面的操作
  3. return view
  4. }else{
  5. return convertView; //进行布局复用
  6. }

上个两种情况下多次滑动列表的日志就一目了然了:

未优化:

优化后:

上面是划了很多下哦。 是不是节省了很多性能。

上代码

my_card_view.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.cardview.widget.CardView
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. android:background="@color/transparent_1"
  7. app:cardCornerRadius="14dp"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content">
  10. <LinearLayout
  11. android:descendantFocusability="blocksDescendants"
  12. android:layout_width="match_parent"
  13. android:layout_height="130dp">
  14. <ImageView
  15. android:id="@+id/card_image"
  16. android:layout_width="120dp"
  17. android:layout_height="140dp"
  18. android:layout_margin="5dp"
  19. android:scaleType="fitCenter"
  20. android:src="@drawable/translate" />
  21. <LinearLayout
  22. android:layout_width="match_parent"
  23. android:layout_height="match_parent"
  24. android:orientation="vertical">
  25. <RelativeLayout
  26. android:layout_width="match_parent"
  27. android:layout_height="wrap_content">
  28. <ImageButton
  29. android:id="@+id/card_collect"
  30. android:layout_width="30dp"
  31. android:layout_height="30dp"
  32. android:layout_alignParentEnd="true"
  33. android:layout_marginTop="10dp"
  34. android:layout_marginEnd="20dp"
  35. android:background="@color/transparent"
  36. android:contentDescription="@string/collect"
  37. android:scaleType="centerCrop"
  38. android:src="@drawable/ic_collect" />
  39. </RelativeLayout>
  40. <TextView
  41. android:id="@+id/card_title"
  42. android:layout_width="match_parent"
  43. android:layout_height="wrap_content"
  44. android:padding="5dp"
  45. android:textSize="18sp"
  46. android:textStyle="bold" />
  47. <TextView
  48. android:id="@+id/card_text"
  49. android:layout_width="match_parent"
  50. android:layout_height="wrap_content"
  51. android:padding="5dp" />
  52. </LinearLayout>
  53. </LinearLayout>
  54. </androidx.cardview.widget.CardView>

fragment_tools.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. android:background="#2F00BCD4"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. tools:context=".ui.tools.ToolsFragment">
  10. <ListView
  11. android:divider="#00000000"
  12. android:dividerHeight="18dp"
  13. android:id="@+id/toollist"
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:layout_marginLeft="20dp"
  17. android:layout_marginRight="20dp">
  18. </ListView>
  19. </RelativeLayout>

ToolsFragment.java

  1. package com.example.testapp.ui.tools;
  2. import android.annotation.SuppressLint;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.widget.AdapterView;
  9. import android.widget.ListView;
  10. import android.widget.Toast;
  11. import androidx.annotation.NonNull;
  12. import androidx.fragment.app.Fragment;
  13. import com.example.testapp.Util.ToolsCardListAdapter;
  14. import com.example.testapp.databinding.FragmentToolsBinding;
  15. import java.util.ArrayList;
  16. import java.util.HashMap;
  17. import java.util.List;
  18. import java.util.Map;
  19. public class ToolsFragment extends Fragment {
  20. private String TAG = "ToolsFragment";
  21. private ListView listView;
  22. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  23. private FragmentToolsBinding binding;
  24. @SuppressLint("ResourceType")
  25. public View onCreateView(@NonNull LayoutInflater inflater,
  26. ViewGroup container, Bundle savedInstanceState) {
  27. binding = FragmentToolsBinding.inflate(inflater, container, false);
  28. View root = binding.getRoot();
  29. String[] urls = new String[]{"https://fanyi-cdn.cdn.bcebos.com/static/translation/img/header/logo_e835568.png",
  30. "https://ssyerv1.oss-cn-hangzhou.aliyuncs.com/picture/55540c3d94454de0a7492fbf13569a96.png",
  31. "https://img-home.csdnimg.cn/images/20201124032511.png",
  32. "https://img-home.csdnimg.cn/images/20201124032511.png"};
  33. String[] titles = new String[]{"查单词","查音标","去CSDN","去CSDN"};
  34. String[] texts = new String[]{"源自百度翻译Api","算了,随便写算了","去CSDN,给勇敢di牛牛点赞","去CSDN,看勇敢di牛牛有没有发布新文章"};
  35. //装填数据
  36. for (int i =0;i < urls.length;i++){
  37. Map<String,Object> map = new HashMap<String,Object>();
  38. map.put("url",urls[i]);
  39. map.put("title",titles[i]);
  40. map.put("text",texts[i]);
  41. list.add(map);
  42. }
  43. ToolsCardListAdapter adapter = new ToolsCardListAdapter(inflater);
  44. listView = binding.toollist;
  45. adapter.setList(list);
  46. listView.setAdapter(adapter);
  47. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  48. @Override
  49. public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
  50. Log.i(TAG, String.format("onItemClick: listviewItem 点击事件生效:第 %s 个!",position));
  51. Toast toast = Toast.makeText(getContext(),String.format("你点击的是第 %d 个Item",position),Toast.LENGTH_SHORT);
  52. toast.show();
  53. }
  54. }
  55. );
  56. return root;
  57. }
  58. @Override
  59. public void onDestroyView() {
  60. super.onDestroyView();
  61. binding = null;
  62. }
  63. }

ToolsCardListAdapter.java

  1. package com.example.testapp.Util;
  2. import static com.example.testapp.R.drawable.ic_collected;
  3. import android.annotation.SuppressLint;
  4. import android.content.Context;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import android.net.Uri;
  8. import android.util.Log;
  9. import android.view.LayoutInflater;
  10. import android.view.View;
  11. import android.view.ViewGroup;
  12. import android.widget.BaseAdapter;
  13. import android.widget.ImageButton;
  14. import android.widget.ImageView;
  15. import android.widget.TextView;
  16. import android.widget.Toast;
  17. import androidx.fragment.app.Fragment;
  18. import com.bumptech.glide.Glide;
  19. import com.example.testapp.R;
  20. import com.example.testapp.ui.tools.ToolsFragment;
  21. import java.util.ArrayList;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.logging.Logger;
  25. public class ToolsCardListAdapter extends BaseAdapter {
  26. String TAG = "ToolsCardListAdapter";
  27. LayoutInflater inflater; //作用相当于FindViewById,反射器
  28. List<Map<String, Object>> list;
  29. public ToolsCardListAdapter(LayoutInflater flater) {
  30. inflater = flater;
  31. }
  32. public void setList(List<Map<String, Object>> list1){
  33. Log.i(TAG, String.format("setList: %s",list1));
  34. list = list1;
  35. }
  36. @Override
  37. public int getCount() {
  38. return list.toArray().length;
  39. }
  40. @Override
  41. public Object getItem(int position) {
  42. return list.get(position);
  43. }
  44. @Override
  45. public long getItemId(int position) {
  46. return position;
  47. }
  48. @Override
  49. public View getView(int position, View convertView, ViewGroup viewGroup) {
  50. if (convertView == null) {
  51. View view = inflater.inflate(R.layout.my_card_view, null);
  52. ImageView imageView = view.findViewById(R.id.card_image);
  53. ImageButton imgButton = view.findViewById(R.id.card_collect);
  54. Log.i(TAG, String.format("getView:创建视图,位置: %s", position));
  55. imgButton.setOnClickListener(new View.OnClickListener() {
  56. @Override
  57. public void onClick(View view) {
  58. imgButton.setImageResource(ic_collected);
  59. Log.i(TAG, "onClick: 你点击了收藏按钮!");
  60. Toast toast = Toast.makeText(inflater.getContext(), String.format("你点击的是第 %d 个收藏按钮", position), Toast.LENGTH_SHORT);
  61. toast.show();
  62. }
  63. });
  64. //Uri uri = Uri.parse((String) list.get(position).get("url"));
  65. Glide.with(imageView).load(list.get(position).get("url")).into(imageView);
  66. //imageView.setImageURI(uri);
  67. TextView title = view.findViewById(R.id.card_title);
  68. TextView text = view.findViewById(R.id.card_text);
  69. title.setText(list.get(position).get("title").toString());
  70. text.setText(list.get(position).get("text").toString());
  71. return view;
  72. }else{
  73. return convertView;
  74. }
  75. }
  76. }

补充

  • 代码有点多,请您见谅,下次我会将项目上传到git。
  • 有啥疑问可以评论区留言或私信。(一定会回)
  • 项目是连贯的,缺的代码在专栏中可以找到。

本文转载自: https://blog.csdn.net/niuguobao/article/details/124482697
版权归原作者 勇敢di牛牛 所有, 如有侵权,请联系我们删除。

“【php + MySQL + Android】在Fragment中实现listview中嵌套cardview”的评论:

还没有评论