Пользовательский ImageButton, какой метод переопределить для простейшего интерфейса RadioButton? - PullRequest
0 голосов
/ 27 мая 2018

Я нахожусь в процессе создания пользовательского представления, которое по сути является ImageButton с добавленной логикой, поэтому оно также имеет поведение RadioButton.Все, что я хочу сделать, - это встроить его в представление о том, что когда пользователь нажимает кнопку, изображение изменяется, внутреннее логическое значение помечается как true, чтобы отметить, что оно выбрано, и вызывается метод интерфейса, позволяющий RadioGroup быть частьючтобы отменить выбор всех других взглядов в нем. Я не хочу влиять на существующее поведение базового ImageButton вообще.

Ранее я сделал только один другой пользовательский вид, и это было следование учебнику почти точно до буквы.и так как в View есть много различных методов, связанных с щелчками / прикосновениями (т. е. onTouch, onClick, motion motion и т. д.), все это меня озадачило.Я прекрасно пишу сам интерфейс, его модификацию ImageButton, где я не слишком уверен, как атаковать его.

Итак, я вас всех спрашиваю: какой метод / методы мне нужно переопределить, чтобы добавить этопростая функциональность, не влияющая на текущее поведение ImageButton, и не испорченная возможностью установить onTouchListener для кнопки, которая будет выполнять дополнительные действия при нажатии без ущерба для этой встроенной логики переключателей?Если мне нужно переопределить что-то, что будет мешать поведению по умолчанию, которое я упомянул, что мне нужно добавить в новый метод для восстановления этой функциональности?

Это то, что я пока имею:

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 по умолчанию и установить мой в качестве близкой реплики, чтобы я мог понять, как он работает, а затем изменить его оттуда, новсе, что я мог действительно найти, было это:

https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r35/core/java/android/widget/ImageButton.java

, и нет никакого способа, который является фактическим источником, потому что нажатие Ctrl + O показывает намного больше функций, которые определяет ImageButton, которые не наследуются отдругой класс;несмотря на это, эта ссылка не очень полезна, так как в основном это гигантский комментарий с небольшим или отсутствующим кодом.

Спасибо за любые предложения, которые помогут мне сделать это самым простым способом.

EDIT: @pskink - просматривая код, который вы предоставили, кажется, что он пытается сгенерировать матрицу, чтобы преобразовать предоставленный объект рисования (src), чтобы он вписался в новый прямоугольник (dst) при сохранениисоотношение сторон и позиционирование (отсюда ScaleToFit.CENTER).Я бы предположил, что прямоугольник назначения был бы границами представления, в котором содержится нарисованный объект, который в данном случае является RadioButton, но, шагая через переопределение метода «draw ()», он, кажется, не делаетэто, хотя я не совсем уверен, как решается cavas.concat (матрица), поэтому я не уверен.Независимо от того, кажется, он не работает как задумано, или я как-то неправильно его использую.

1 Ответ

0 голосов
/ 29 мая 2018

Хотя, возможно, это и не самый надежный метод, он кажется наиболее простым, но эффективным способом решения того, что я хотел сделать, - это использовать класс Matrix и его мощные инструменты масштабирования / преобразования, в частности, setRectToRect ().Создание настраиваемого представления, расширяющего RadioButton вместо ImageButton, позволило мне использовать существующую RadioGroup, в то же время манипулируя характеристиками объектов кнопки в новых классах. Конструктор получил искомое поведение.

Пользовательский класс RadioButton:

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
    }
}

Подробнее о настройке настраиваемого представления см. Здесь: https://developer.android.com/training/custom-views/create-view#customattr

Настраиваемый класс рисования "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);
    }
}

Обратите внимание, что по какой-либо причине установка самой кнопки для рисования в этот пользовательский рисунок нарушает масштабирование, поэтому изменение фона на пользовательский рисунок и установка кнопки в прозрачный режим было единственным способом, которым это работало.Этот пользовательский объект рисования может быть легко расширен, чтобы иметь больше опций типа масштабирования, а другой атрибут представления может быть определен, чтобы позволить пользователю выбирать тип масштабирования через XML.

Этот пользовательский ImageView, который имитирует (указывает pskinkaswell) также может оказаться полезным в этой задаче, поскольку он также использует класс Matrix для реализации нескольких типов масштабирования изображения: https://github.com/yqritc/Android-ScalableImageView

...