Android 自定义ImageButton,最简单的RadioButton界面要覆盖哪种方法?
我正在制作一个自定义视图,它本质上是一个带有附加逻辑的ImageButton,因此它也具有RadioButton的行为。我所要做的就是将其内置到视图中,当用户单击按钮时,图像被更改,一个内部布尔值被标记为true,以说明它被选中,并且调用一个接口方法,让它所属的放射组取消选中其中的所有其他视图我不想影响基本ImageButton的现有行为。 我以前只做过一个自定义视图,它几乎完全按照教程进行操作,因为视图中有很多不同的方法来处理点击/触摸(即onTouch、onClick、motion event等),所以将所有这些都纳入其中让我有点困惑。我很好地编写了界面本身,它是对ImageButton的修改,我不太确定如何攻击它 所以,我想问大家:我需要覆盖哪些方法来添加这个简单的功能,同时既不影响ImageButton的当前行为,也不破坏为按钮设置onTouchListener的能力,以便在不影响内置单选按钮逻辑的情况下,在点击时执行其他操作?如果我需要重写一些会破坏我提到的默认行为的东西,我需要在新方法中添加什么来恢复该功能 这就是我到目前为止所做的:Android 自定义ImageButton,最简单的RadioButton界面要覆盖哪种方法?,android,radio-button,android-custom-view,ontouchlistener,android-imagebutton,Android,Radio Button,Android Custom View,Ontouchlistener,Android Imagebutton,我正在制作一个自定义视图,它本质上是一个带有附加逻辑的ImageButton,因此它也具有RadioButton的行为。我所要做的就是将其内置到视图中,当用户单击按钮时,图像被更改,一个内部布尔值被标记为true,以说明它被选中,并且调用一个接口方法,让它所属的放射组取消选中其中的所有其他视图我不想影响基本ImageButton的现有行为。 我以前只做过一个自定义视图,它几乎完全按照教程进行操作,因为视图中有很多不同的方法来处理点击/触摸(即onTouch、onClick、motion even
public class RadioImageButton extends AppCompatImageButton implements RadioCheckable {
//Default constructor
public RadioImageButton(Context context) {
super(context);
initView();
}
//Constructor with defined attributes
public RadioImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes();
initView();
}
//Constructor with defined attributes and attributes taken from style defaults that aren't defined
public RadioImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//=========================================================================
// Setup
//=========================================================================
private void initView()
{
}
private void parseAttributes()
{
}
}
我想采取的方法是:
...All other code I already showed
mChecked = false;
@Overide
void onClick(...)
{
mChecked = true;
setImageSource(R.example.checked_image); // Or I can use a selector resource
*Call to Radio Interface*;
mOnTouchListener.onTouch(v, event); //Handle user onTouchListener
}
...
不要管其他的代码,尽管我相信它不是那么简单
我认为一个好的开始是尝试找到默认ImageButton类的源代码,并将我的设置为近似副本,这样我就可以理解它的工作原理,然后从那里进行修改,但我真正能找到的是:
而且不可能是实际的源代码,因为按Ctrl+O键会显示ImageButton定义的更多函数,这些函数不是从另一个类继承的;不管怎样,这个链接一点帮助都没有,因为它基本上是一个巨大的注释,几乎没有代码
谢谢你的建议,这些建议将帮助我以最直接的方式完成这项任务
编辑:@pskink-查看您提供的代码,它似乎在试图生成一个矩阵,以便转换提供的可绘制(src),以便在保持纵横比和定位(因此ScaleToFit.CENTER)的同时将其放入新的矩形(dst)。我假设目标矩形是包含可绘制内容的视图的边界,在本例中是单选按钮,但在逐步覆盖“draw()”方法时,它似乎并没有这样做,尽管我不太确定cavas.concat(matrix)是如何解析的,所以我不是肯定的。无论如何,它似乎没有按预期的那样工作,或者我用错了它。虽然它可能不是最健壮的方法,但它似乎是处理我想做的事情的最直接、最有效的方法,就是利用Matrix类及其强大的缩放/转换工具,特别是“setRectToRect()”。创建一个扩展RadioButton而不是ImageButton的自定义视图使我能够利用现有的RadioGroup,同时在新的类构造函数中操纵按钮的可绘制项的特征实现了我想要的行为 自定义单选按钮类:
public class RadioImageButton extends android.support.v7.widget.AppCompatRadioButton {
int stateDrawable; //Resource ID for RadioButton selector Drawable
D scaledDrawable; //Post-scaling drawable
public RadioImageButtonTwo(Context context) {
super(context);
initView();
}
public RadioImageButtonTwo(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(attrs);
initView();
}
private void parseAttributes(AttributeSet attrs)
{
TypedArray styledAttrs = getContext().obtainStyledAttributes(attrs,R.styleable.RadioImageButtonTwo);
try {
// Obtain selector drawable from attributes
stateDrawable = styledAttrs.getResourceId(R.styleable.RadioImageButtonTwo_button_sDrawable, R.drawable.test_draw2);
} finally {
styledAttrs.recycle(); //Required for public shared view
}
}
private void initView()
{
scaledDrawable = new D(getResources(),stateDrawable); // Create scaled drawable
setBackground(scaledDrawable); // Apply scaled drawable
setButtonDrawable(android.R.color.transparent); // "Disable" button graphic
}
}
请参见此处有关设置自定义视图的详细信息:
定制可拉伸“D”级,包括fitCenter缩放,感谢@pskink:
class D extends StateListDrawable {
private Rect bounds = new Rect();
private RectF src = new RectF();
private RectF dst = new RectF();
private Matrix matrix = new Matrix();
public D(Resources r, int resId) {
try {
XmlResourceParser parser = r.getXml(resId);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG && parser.getName().equals("selector")) {
inflate(r, parser, Xml.asAttributeSet(parser));
break;
}
}
} catch (XmlPullParserException | IOException e) {
e.printStackTrace();
}
}
@Override
public void draw(Canvas canvas) {
Drawable current = getCurrent();
bounds.set(0, 0, current.getIntrinsicWidth(), current.getIntrinsicHeight());
current.setBounds(bounds);
src.set(bounds);
dst.set(getBounds());
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
canvas.concat(matrix);
super.draw(canvas);
}
}
请注意,无论出于何种原因,将按钮drawable自身设置为此自定义drawable都会破坏缩放效果,因此将背景更改为自定义drawable并将按钮drawable设置为透明是唯一可行的方法。这个定制的可绘制文件可以很容易地扩展,以具有更多的缩放类型选项,并且可以定义另一个视图属性,以允许用户通过XML选择缩放类型
这个定制的ImageView模仿了(pskink也指出了这一点)在这项任务中也会很有帮助,因为它也利用Matrix类来实现多种类型的图像缩放:如果您看一下的代码,它可能会更清晰,这是
RadioButton
的超类。但是,RadioGroup
仅适用于RadioButton
s,因此您必须为单个选择编写自己的ViewGroup
或单独的逻辑,或者子类RadioButton
,并集成您试图利用的ImageButton
/ImageView
的那些功能。使用普通的RadioButton
-事实上您甚至不必扩展它-您只需编写一个自定义的可绘制的(很可能是扩展StateListDrawable
?)并与视图一起使用
method@pskink我很确定他们正在尝试利用ImageView
的/ImageButton
的内置缩放模式。看看他们之前的问题。这就是为什么如果他们走那条路,就必须将RadioButton子类化。@MikeM。是的,事实上,你才是真正的福尔摩斯,我甚至想不起找到之前的问题……;-)@米肯。但事实上,我看到一些第三方代码模仿了所有ImageView
的缩放类型,转换成Matrix
,因此您真正需要的是一个自定义可绘制的
,其中仅显示根据缩放类型进行更改-类似于如果您扩展RadioButton
,则无需使用自定义的D
可绘制,请参见:Lol.再次查看。几天后回到家后,我会切换到这个问题,并更新答案。因为可绘制的缩放是RadioButton的一部分,所以这一点确实要简单一些