一个简单自定义单选控件,传入图片资源即可
上代码:
package com.example.SecondProject.View;
import android.content.Context;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
// 单选组:LinearLayout 传入图片id
public class RadioGroupLinearLayout extends LinearLayout {
private String TAG = "RadioGroupLinearLayout";
private ImageView lastCheckedIcon; // 最后选中的icon
private int[] iconResIds; // 选项图标资源
private int iconWidth = 80;
private int iconHeight = 80;
public RadioGroupLinearLayout(Context context) {
super(context);
init();
}
public RadioGroupLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RadioGroupLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setOrientation(HORIZONTAL);
}
public void setIcons(int[] iconResIds,int default_index,int iconWidth,int iconHeight) {
this.iconResIds = iconResIds; // 选项图标资源
setIconsSize(iconWidth,iconHeight); // 设置选项图标大小
createIconRadioButtons(default_index); // 初始化选项
}
// 设置选项图标大小
public void setIconsSize(int iconWidth,int iconHeight){
this.iconWidth = dp2px(getContext(),iconWidth);
this.iconHeight = dp2px(getContext(),iconHeight);
}
// dp转px
public static int dp2px(Context context, float dp) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5F);
}
// 初始化选项:传入默认选项的索引
private void createIconRadioButtons(int default_index) {
removeAllViews();
for (int i = 0; i < iconResIds.length; i++) {
final ImageView icon = new ImageView(getContext());
// LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); // 设置图标的大小为自适应
LayoutParams params = new LayoutParams(iconWidth,iconHeight); // 设置图标的大小
params.weight = 1;
icon.setLayoutParams(params);
icon.setImageResource(iconResIds[i]);
setGrayColorFilter(icon);
int finalI = i;
icon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (lastCheckedIcon==icon){return;} // 仍然是上次选中的
setGrayColorFilter(lastCheckedIcon); // 点击新的图标时把上一个图片褪色
lastCheckedIcon = icon;
lastCheckedIcon.clearColorFilter(); // 清除褪色效果
Log.e(TAG, "变身" );
if (onItemClickListener!=null){onItemClickListener.onItemClick(finalI);}
}
});
addView(icon); // 添加图标
// 设置默认选项
if (i == default_index) {
lastCheckedIcon = icon;
lastCheckedIcon.clearColorFilter();
if (onItemClickListener!=null){onItemClickListener.onItemClick(i);}
}
}
}
// 设置褪色效果
private void setGrayColorFilter(ImageView icon) {
if(icon==null){return;}
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
icon.setColorFilter(colorFilter);
}
// 接口 ----------------------------------------------------
public interface onItemClickListener{
void onItemClick(int index);
}
public onItemClickListener onItemClickListener;
public void setOnItemClickListener(onItemClickListener onItemClickListener){this.onItemClickListener = onItemClickListener;}
}
使用方法:
代码:
package com.example.SecondProject
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.SecondProject.View.RadioGroupLinearLayout
import com.example.SecondProject.databinding.ActivityRadioGroupBinding
class RadioGroupActivity: AppCompatActivity() {
val TAG = "RadioGroupActivity"
lateinit var binding:ActivityRadioGroupBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRadioGroupBinding.inflate(layoutInflater)
setContentView(binding.root)
// 创建资源文件
val iconResIds = intArrayOf(
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko,
R.drawable.chibi_maruko
)
binding.radioGroup.setIcons(iconResIds,4,30,30) // 设置默认选项和图标大小
// 设置点击事件
binding.radioGroup.setOnItemClickListener(object :RadioGroupLinearLayout.onItemClickListener{
override fun onItemClick(index: Int) {
Log.e(TAG, "当前选中项: $index" )
}
})
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<com.example.SecondProject.View.RadioGroupLinearLayout
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
点击效果:
总体思路:
总体思路很简单:自定义一个 LinearLayout 设置为横向布局,并将传入的图片资源文件id逐个按照比重为1添加进去。定义一个 ImageView 对象作为最后选中的对象,当点击新的选项时把最后选中的对象去色并将自身定义为最后选中的对象再恢复颜色同时把点击的索引传出去。