实现android自定义下拉选择框,可随意更改样式
程序员文章站
2022-06-07 17:58:15
...
先看效果图是否合口
在登录界面选择角色,上下箭头是会变化的,默认是选择学生,当选择老师时,对应的icon、文字相应的改变(样式可以随意更改)。
使用的是RecycleView+自定义适配器+PopupWindow实现的:
1.准备好一个item_login_role.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cl_item_loginRole_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/spacing_5"
android:background="@color/login_role_bg">
<ImageView
android:id="@+id/iv_item_loginRole"
android:layout_width="@dimen/spacing_22"
android:layout_height="@dimen/spacing_22"
android:layout_marginLeft="@dimen/spacing_32"
android:layout_marginTop="@dimen/spacing_12"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/tv_item_loginRole"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/spacing_9"
android:textSize="@dimen/font_15"
android:textColor="@color/text_black1"
app:layout_constraintLeft_toRightOf="@id/iv_item_loginRole"
app:layout_constraintTop_toTopOf="@+id/iv_item_loginRole"
app:layout_constraintBottom_toBottomOf="@+id/iv_item_loginRole"/>
</android.support.constraint.ConstraintLayout>
2.自定义适配器LoginRoleAdapter
/**
* 登录角色选择时
* Created by Administrator on 2019/11/19
*
* @author mcl
*/
public class LoginRoleAdapter extends RecyclerView.Adapter {
private Context mContext;
private List<RoleBean> mList;
private int selected = -1;
private OnItemClickLitener mOnItemClickListener;
public interface OnItemClickLitener {//点击事件回调
void onItemClick(View view, int position);
}
public LoginRoleAdapter(Context context, List<RoleBean> list) {
this.mContext = context;
this.mList = list;
}
public void setmOnItemClickListener(OnItemClickLitener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_login_role, viewGroup, false);
return new LoginRoleViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int i) {
if (holder instanceof LoginRoleViewHolder){
final LoginRoleViewHolder viewHolder=(LoginRoleViewHolder)holder;
viewHolder.tvRole.setText(mList.get(i).getRoleName());
viewHolder.ivRole.setBackgroundResource(ResUtils.getId(mContext,mList.get(i).getRoleIcon(),ResUtils.MIPMAP));
if (null!=mOnItemClickListener){
viewHolder.cl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickListener.onItemClick(viewHolder.itemView,viewHolder.getAdapterPosition());
}
});
}
}
}
@Override
public int getItemCount() {
if (null != mList && mList.size() > 0) {
return mList.size();
} else {
return 0;
}
}
class LoginRoleViewHolder extends RecyclerView.ViewHolder {
private ConstraintLayout cl;
private ImageView ivRole;
private TextView tvRole;
public LoginRoleViewHolder(@NonNull View itemView) {
super(itemView);
cl = itemView.findViewById(R.id.cl_item_loginRole_view);
ivRole = itemView.findViewById(R.id.iv_item_loginRole);
tvRole = itemView.findViewById(R.id.tv_item_loginRole);
}
}
}
3.在activity里面:填充数据,及选择后回调,显示相应的文字、icon……
private RecyclerView recyclerView;
RoleBean role = new RoleBean();
role.setRoleName(this.getString(R.string.module_app_login_login_teacher_role));
role.setRoleIcon("login_teacher_btn");
role.setUserrole("S03");
roleList.add(role);
RoleBean role1 = new RoleBean();
role1.setRoleName(this.getString(R.string.module_app_login_login_parent_role));
role1.setRoleIcon("login_parent_btn");
role.setUserrole("S04");
roleList.add(role1);
LoginRoleAdapter adapter = new LoginRoleAdapter(this, roleList);
recyclerView = new RecyclerView(this);
recyclerView.setVerticalScrollBarEnabled(false);//隐藏滚动条
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter.setmOnItemClickListener(new LoginRoleAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
binding.tvLoginRole.setText(roleList.get(position).getRoleName());
binding.ivLoginRole.setBackgroundResource(ResUtils.getId(LoginActivity.this, roleList.get(position).getRoleIcon(), ResUtils.MIPMAP));
binding.ivLoginDirection.setBackgroundResource(ResUtils.getId(LoginActivity.this, "login_arrow_down", ResUtils.MIPMAP));//向下的图标
userrole=roleList.get(position).getUserrole();
window.dismiss();
}
});
4.登录界面的布局这里就省略了(不要在布局里面放icon,不然会重叠,在对应代码里面放),点击时,创建PopupWindow
项目用到的是dataBinding数据绑定,binding.ivLoginDirection指的是图标ImageView控件。
/**
* 选择角色点击事件
*
* @param view
*/
public void clickRole(View view) {
binding.ivLoginDirection.setBackgroundResource(ResUtils.getId(this, "login_arrow_up", ResUtils.MIPMAP));//向上的图标
if (window == null) {
//在binding.rlLoginRole控件下显示PopupWindow,一般长度就跟它一样,所以参数2是这么写的
window = new PopupWindow(recyclerView, binding.rlLoginRole.getWidth(), RecyclerView.LayoutParams.WRAP_CONTENT);
}
window.setFocusable(true);//要让其中的view获取焦点,必须设置为true
window.setOutsideTouchable(true);//设置点击外部消失
window.showAsDropDown(binding.rlLoginRole, 0, 0);//binding.rlLoginRole要在哪个控件下显示
}
5.补充RoleBean就三个属性,进行get、set方法即可,如下:
/**
* Created by Administrator on 2019/11/19
*
* @author mcl
*/
public class RoleBean {
private String roleIcon;
private String roleName;
private String userrole;
public String getRoleIcon() {
return roleIcon;
}
public void setRoleIcon(String roleIcon) {
this.roleIcon = roleIcon;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getUserrole() {
return userrole;
}
public void setUserrole(String userrole) {
this.userrole = userrole;
}
}
用了最笨的方法,虽然能满足需求,但是不够优化,有更好的方式,可以帮提点一下,感激不尽!
下一篇: Vue实现组件自定义数据双向绑定