使用方式:
private TableListView tableListView;
tableListView = view.findViewById(R.id.ts_table);
tableListView.builder(mContext,table,new HashMap<String, Object>(){{ put("time","时间"); put("data","用量"); put("cost","成本"); }});
效果:
通用适配器
Adapter:
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import androidx.annotation.NonNull; import java.util.List; import java.util.Map; public abstract class ListViewAdapter extends ArrayAdapter<Map<String,Object>> { private ViewHolder holder; private int resourceId; private static final int MAX_ITEM_COUNT = 4; public ListViewAdapter(@NonNull Context context, int resource, @NonNull List<Map<String, Object>> mapList) { super(context, resource, mapList); this.resourceId = resource; } @Override public View getView(int position, View convertView, @NonNull ViewGroup parent){ Map<String,Object> map = getItem(position); // 加个判断,以免ListView每次滚动时都要重新加载布局,以提高运行效率 View view; if (convertView==null){ // 避免ListView每次滚动时都要重新加载布局,以提高运行效率 view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false); holder = new ViewHolder(view); // 将ViewHolder存储在View中(即将控件的实例存储在其中) view.setTag(holder); } else { view = convertView; holder = (ViewHolder) view.getTag(); } // 控件实例 setData(holder,map,position); return view; } /** 写布局元素 */ public abstract void setData(ViewHolder holder,Map<String,Object> map,int position); }
通用ViewHolder
ViewHolder:
import android.content.Context; import android.os.Build; import android.util.SparseArray; import android.view.View; import android.widget.Adapter; import android.widget.TextView; import androidx.annotation.RequiresApi; import com.ln.ln_app.utility.CString; import java.util.Map; public class ViewHolder { public final SparseArray<View> views; private View convertView; private Adapter adapter; private Context context; public ViewHolder(View convertView) { this.views = new SparseArray<View>(); this.convertView = convertView; } public <T extends View> T getView(int viewId) { View view = views.get(viewId); if (view == null) { view = convertView.findViewById(viewId); views.put(viewId, view); } return (T) view; } public Adapter getAdapter() { return adapter; } /** 根据map的key自动绑定textview @RequiresApi(api = Build.VERSION_CODES.M) public void dataBinding(Context context,Map<String,Object> map){ if(map.size() > 0) { for (String key : map.keySet()) { /** 获取资源id */ int id = convertView.getResources().getIdentifier(key, "id", context.getApplicationContext().getPackageName()); View view = getView(id); if(view != null) { String[] viewType = view.getAccessibilityClassName().toString().split("\\."); if(viewType.length > 0){ switch (viewType[viewType.length - 1]){ case "TextView": ((TextView)view).setText(CString.get(map,key)); break; case "": break; } } } } } } public void setAdapter(Adapter adapter) { this.adapter = adapter; } }
封装ListView
TableListView:
import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import com.ln.ln_app.R; import com.ln.ln_app.ui.adapter.base.ListViewAdapter; import com.ln.ln_app.ui.adapter.base.ViewHolder; import com.ln.ln_app.utility.CString; import java.util.ArrayList; import java.util.List; import java.util.Map; public class TableListView extends RelativeLayout { private View view; private ListViewAdapter listViewAdapterTitle,listViewAdapterBody; public TableListView(Context context, AttributeSet attrs) { super(context, attrs); /** 加载布局 */ view = LayoutInflater.from(context).inflate(R.layout.fragment_table, this); } public void builder(Context mContext,List<Map<String,Object>> mapList, Map<String,Object> titleMap){ if(mapList.size() > 0) { if(mapList.get(0).size() > 5) return; int id = getLoyoutId(mapList.get(0).size()); /** 适配表头信息 */ listViewAdapterTitle = new ListViewAdapter(mContext, id, new ArrayList<Map<String,Object>>(){{ add(mapList.get(0)); }}) { @Override public void setData(ViewHolder holder, Map<String, Object> map,int position) { if(titleMap != null && titleMap.size() > 0){ setTitle(holder,map,titleMap); } else { setTitle(holder,map); } } }; ListView titleView = view.findViewById(R.id.lv_table_title); titleView.setAdapter(listViewAdapterTitle); /** 适配表体信息 */ listViewAdapterBody = new ListViewAdapter(mContext, id, mapList) { @Override public void setData(ViewHolder holder, Map<String, Object> map,int position) { setBody(holder,map); } }; ListView bodyView = view.findViewById(R.id.lv_table_body); bodyView.setAdapter(listViewAdapterBody); } } public void builder(Context mContext,List<Map<String,Object>> mapList){ builder(mContext,mapList,null); } /** * 获取资源id * @param col * @return */ private int getLoyoutId(int col){ /** 获取资源id */ int id = 0; switch (col){ case 1: id = R.layout.fragment_table_style_1; break; case 2: id = R.layout.fragment_table_style_2; break; case 3: id = R.layout.fragment_table_style_3; break; case 4: id = R.layout.fragment_table_style_4; break; case 5: id = R.layout.fragment_table_style_5; break; } return id; } /** * 适配表头 * @param holder * @param map */ private void setTitle(ViewHolder holder, Map<String, Object> map){ setTitle(holder,map,null); } private void setTitle(ViewHolder holder, Map<String, Object> map, Map<String, Object> titleMap){ if(map == null) return; if(map.size() > 0) { int i = 1; for(String key : map.keySet()){ TextView tv = holder.getView(getResId(i)); if(titleMap != null && titleMap.containsKey(key)){ tv.setText(CString.get(titleMap,key)); } else { tv.setText(key); } i++; } } } /** * 适配表体 * @param holder * @param map */ private void setBody(ViewHolder holder, Map<String, Object> map){ if(map == null) return; if(map.size() > 0) { int i = 1; for(String key : map.keySet()){ TextView tv = holder.getView(getResId(i)); tv.setText(CString.get(map,key)); i++; } } } /** * 获取资源id * @param col * @return */ private int getResId(int col){ /** 获取资源id */ int id = 0; switch (col){ case 1: id = R.id.title_1; break; case 2: id = R.id.title_2; break; case 3: id = R.id.title_3; break; case 4: id = R.id.title_4; break; case 5: id = R.id.title_5; break; } return id; } }
表格标题及表体 fragment_table.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" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" android:background="@android:color/white"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/lv_table_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:listSelector="@android:color/transparent" android:fastScrollEnabled="false" android:scrollbars="none" android:divider="@null" android:groupIndicator="@null" android:layoutDirection="ltr"/> <ListView android:id="@+id/lv_table_body" android:layout_width="match_parent" android:layout_height="match_parent" android:listSelector="@android:color/transparent" android:fastScrollEnabled="false" android:scrollbars="none" android:divider="@null" android:groupIndicator="@null" android:layoutDirection="ltr"/> </LinearLayout> </RelativeLayout>
只处理到最大5字段表格,创建5个xml分别对应1~5个字段的表格
fragment_table_style_5.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="30dp" android:orientation="horizontal"> <TextView android:id="@+id/title_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_weight="1" android:text="title_1" android:textSize="14sp"/> <TextView android:id="@+id/title_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_weight="1" android:text="title_2" android:textSize="14sp"/> <TextView android:id="@+id/title_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_weight="1" android:text="title_3" android:textSize="14sp"/> <TextView android:id="@+id/title_4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_weight="1" android:text="title_4" android:textSize="14sp"/> <TextView android:id="@+id/title_5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_weight="1" android:text="title_5" android:textSize="14sp"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginTop="2dp" android:background="@color/divider"/> </LinearLayout>