最近自定义了评价星星的view,可以直接xml上更改各种属性(评价的类型,评价的星星数量,默认评价的数量)
先看一下效果图:
当设置评价的类型为3种类型,名称为:描述相符,物流服务,服务态度;每种评价的星星数量为5;默认为1颗星
当设置评价的类型为4种类型,名称为:描述相符,物流服务,服务态度,产品质量;每种评价的星星数量为3;默认为3颗星
实现的原理是:把每一行评价,包括评价类型,评价星星看作是listview中的一个item,每个item中的星星又看作一个小的listview,
下面把代码贴出来:
1. StartSetView:自定义view
public class StartSetView extends LinearLayout { int typs=3;//多少级 List<String> names=new ArrayList<String>();//每一级的名称(质量/综合/物流等等) int start_num=5;//每级多少星星 int default_num=3;//默认多少星 List<StartTypeBean> list=new ArrayList<StartTypeBean>(); RecyclerView startTypeLv; StartTypeAdapter typeAdapter; Context context; public StartSetView(Context context,int typs,List<String> names,int start_num,int default_num) { super(context); initView( context,null); this.typs=typs; this.names=names; this.start_num=start_num; this.default_num=default_num; this.context=context; initData(); } public StartSetView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); this.context=context; initView( context,attrs); initData(); } public StartSetView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context=context; initView( context,attrs); initData(); } public StartSetView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); this.context=context; initView( context,attrs); initData(); } void initView(Context context,AttributeSet attrs){ LayoutInflater.from(context).inflate(R.layout.start_set_view, this, true); startTypeLv=this.findViewById(R.id.start_type_lv); if(attrs!=null) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.startview); typs = ta.getInteger(R.styleable.startview_types, 3); start_num = ta.getInteger(R.styleable.startview_start_num, 5); default_num = ta.getInteger(R.styleable.startview_default_num, 3); String namestr=ta.getString(R.styleable.startview_names); Log.d("Test","types"+typs); Log.d("Test","start_num"+start_num); Log.d("Test","default_num"+default_num); Log.d("Test","namestr"+namestr); if(namestr!=null&&!namestr.equals("")){ String[] strs=namestr.split(","); for(int i=0;i<strs.length;i++){ names.add(strs[i]); } } ta.recycle(); } } void initData(){ if(names.size()==0){ names.add("质量") ; names.add("综合"); names.add("物流"); } for(int i=0;i<typs;i++){ StartTypeBean startTypeBean=new StartTypeBean(); if(i<names.size()) { startTypeBean.setName(names.get(i)); } List<StartBean> startBeans=new ArrayList<StartBean>(); for(int j=0;j<start_num;j++){ StartBean bean=new StartBean(); if(j<default_num){ bean.setChoose(true); } startBeans.add(bean); } startTypeBean.setStarts(startBeans); list.add(startTypeBean); } if(list!=null&&list.size()>0){ typeAdapter=new StartTypeAdapter(context,list); LinearLayoutManager manager=new LinearLayoutManager(context); startTypeLv.setLayoutManager(manager); startTypeLv.setAdapter(typeAdapter); } } }2.自定义view 布局R.layout.start_set_view
<?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" > <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/start_type_lv" /> </LinearLayout>3.自定义view里面会涉及到两个adapter,外层的和内层的:
3.1:StartTypeAdapter
public class StartTypeAdapter extends RecyclerView.Adapter<StartTypeAdapter.ViewHolder> { Context context; LayoutInflater inflater; List<StartTypeBean> list; public StartTypeAdapter(Context context, List<StartTypeBean> list) { this.context = context; this.list = list; this.inflater = LayoutInflater.from(context); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.start_type_item_layout, parent, false); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { StartTypeBean bean=list.get(position); String name=bean.getName(); if(name!=null){ holder.nameTv.setText(name); } if(bean.getStarts()!=null){ StartAdapter startAdapter=new StartAdapter(context,bean.getStarts()); LinearLayoutManager manager=new LinearLayoutManager(context,RecyclerView.HORIZONTAL,false); holder.startsRv.setLayoutManager(manager); holder.startsRv.setAdapter(startAdapter); } } @Override public int getItemCount() { return list.size(); } class ViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.starts_rv) RecyclerView startsRv; @BindView(R.id.name_tv) TextView nameTv; public ViewHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this,itemView); } } }布局:
<?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="horizontal" android:padding="10dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="质量" android:id="@+id/name_tv" /> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/starts_rv" android:layout_marginLeft="10dp" /> </LinearLayout>3.2 StartAdapter
public class StartAdapter extends RecyclerView.Adapter<StartAdapter.ViewHolder> { Context context; LayoutInflater inflater; List<StartBean> list; public StartAdapter(Context context, List<StartBean> list) { this.context = context; this.list = list; this.inflater = LayoutInflater.from(context); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.start_item_layout, parent, false); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { StartBean bean=list.get(position); if(bean.isChoose()){ holder.ivIcon.setImageResource(R.mipmap.pj);//选择的时候亮星星的图片 }else{ holder.ivIcon.setImageResource(R.mipmap.pj_n);//不选择的时候星星灰色的图片 } } @Override public int getItemCount() { return list.size(); } class ViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.iv_icon) ImageView ivIcon; public ViewHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this, itemView); } } }布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:padding="2.5dp" > <ImageView android:layout_width="15dp" android:layout_height="15dp" android:src="@mipmap/pj" android:id="@+id/iv_icon" /> </LinearLayout>4.其中的自定义属性文件:attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="startview"> <attr name="types" format="integer" /> <attr name="start_num" format="integer" /> <attr name="default_num" format="integer" /> <attr name="names" format="string" /> </declare-styleable> </resources>5.activity引用:
5.1布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <com.example.testdemoactivity.view.StartSetView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/start" app:types="4" app:start_num="3" app:default_num="3" app:names="描述相符,物流服务,服务态度,产品质量" /> </LinearLayout>5.2:activity:暂时没有添加其他点击的事件,自定义view中也还没有添加
public class StartCommentActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.start_comment_activity); } }