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

功能介绍:

  • 效果视频:

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

目录

功能介绍:

重难点梳理:

关于listview适配器Adapter

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

 怎么通过Adapter把我在xml中写的相关的view加进去

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

关于点击事件的添加:

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

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

itemview点击事件不生效怎么办: 

关于加载网络图片

关于布局

每个Itemview之间的间距:

其他:

Adapter的优化

上代码

my_card_view.xml

fragment_tools.xml

ToolsFragment.java

 ToolsCardListAdapter.java

补充


重难点梳理:

  • 关于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"

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

  • 其他:

1.

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。
  • 有啥疑问可以评论区留言或私信。(一定会回)
  • 项目是连贯的,缺的代码在专栏中可以找到。

猜你喜欢

转载自blog.csdn.net/niuguobao/article/details/124482697