Есть ли способ повернуть кнопку без использования анимации в Android 2.1 - PullRequest
5 голосов
/ 08 ноября 2011

Я в поиске методологии для поворота кнопки. без использования анимации ..!

Я не хочу использовать анимацию из-за этого.

если у кого-нибудь есть идеи, пожалуйста, помогите мне.

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:id="@+id/ll" android:gravity="center_vertical">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="@string/hello" />
    <com.mind.RotateButton android:layout_width="100dp"  android:gravity="center_vertical"
        android:layout_height="100dp" android:id="@+id/ll1">
    <Button android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="Button" android:id="@+id/but" />
    </com.mind.RotateButton>
</LinearLayout>

код

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);      
        Button btn   = (Button) findViewById(R.id.but);     
        btn.setOnClickListener(new OnClickListener() {          
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_SHORT).show();                
            }
        });
    }

Заранее спасибо .......!

Ответы [ 2 ]

1 голос
/ 08 ноября 2011

расширение Класс кнопки:

public class RotateButton extends Button{

    public RotateButton(Context context) {
        super(context);
    }

    public RotateButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.rotate(45, getWidth() / 2, getHeight() / 2);
        super.onDraw(canvas);
        canvas.restore();
    }

}

и в вашем макете:

<com.samples.myapp.ui.RotateButton
        android:layout_height="wrap_content" android:id="@+id/MyBtn"
        android:padding="5dip" android:textColor="@color/darkGreen"
        android:textSize="16dip" android:text="TextView"
        android:layout_width="wrap_content"></com.samples.myapp.ui.RotateButton>

----------------------------------------------------------------------

edit:

Другой подход: создать вращающийся LinearLayout и поместить в него элементы управления.LinearLayout можно вращать полностью:

package org.mabna.order.ui;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class RotateLinearLayout extends LinearLayout{

    private Matrix mForward = new Matrix();
    private Matrix mReverse = new Matrix();
    private float[] mTemp = new float[2];

    public RotateLinearLayout(Context context) {
        super(context);
    }

    public RotateLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {

        canvas.rotate(180, getWidth() / 2, getHeight() / 2);

        mForward = canvas.getMatrix();
        mForward.invert(mReverse);
        canvas.save();
        canvas.setMatrix(mForward); // This is the matrix we need to use for
                                    // proper positioning of touch events
        super.dispatchDraw(canvas);
        canvas.restore();
        invalidate();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        event.setLocation(getWidth() - event.getX(), getHeight() - event.getY());
        return super.dispatchTouchEvent(event);
    }
}
0 голосов
/ 16 ноября 2011

Используя идеи из breceivemail answer, я сделал rotate layout, который действительно работает. Он предназначен для хранения одного представления, он будет правильно отправлять сенсорные события, но в этой реализации не поддерживаются отступы или поля. Кроме того, он поддерживает только такие углы, как 90, 180, 270 и т. Д. Размер макета будет соответствовать размеру его дочернего элемента после поворота.

public class RotateLayout extends ViewGroup {

    public static class LayoutParams extends ViewGroup.LayoutParams {

        public int angle;

        public LayoutParams(Context context, AttributeSet attrs) {
            super(context, attrs);
            final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotateLayout_Layout);
            angle = a.getInt(R.styleable.RotateLayout_Layout_layout_angle, 0);
        }

        public LayoutParams(ViewGroup.LayoutParams layoutParams) {
            super(layoutParams);
        }

    }

    public RotateLayout(Context context) {
        super(context);
    }

    public RotateLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setWillNotDraw(false);
    }

    public View getView() {
        return view;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view = getChildAt(0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
        if(angle != layoutParams.angle) {
            angle = layoutParams.angle;
            angleChanged = true;
        }

        if(Math.abs(angle % 180) == 90) {
            measureChild(view, heightMeasureSpec, widthMeasureSpec);
            setMeasuredDimension(
                resolveSize(view.getMeasuredHeight(), widthMeasureSpec), 
                resolveSize(view.getMeasuredWidth(), heightMeasureSpec));
        }
        else {
            measureChild(view, widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(
                resolveSize(view.getMeasuredWidth(), widthMeasureSpec), 
                resolveSize(view.getMeasuredHeight(), heightMeasureSpec));
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(changed || angleChanged) {
            layoutRectF.set(0, 0, r - l, b - t);
            layoutTransitionMatrix.setRotate(angle, layoutRectF.centerX(), layoutRectF.centerY());
            layoutTransitionMatrix.mapRect(layoutRectFRotated, layoutRectF);
            layoutRectFRotated.round(viewRectRotated);
            angleChanged = false;
        }

        view.layout(viewRectRotated.left, viewRectRotated.top, viewRectRotated.right, viewRectRotated.bottom);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        canvas.rotate(-angle, getWidth() / 2f, getHeight() / 2f);
        super.dispatchDraw(canvas);
        canvas.restore();
    }

    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        invalidate();
        return super.invalidateChildInParent(location, dirty);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        touchPoint[0] = event.getX();
        touchPoint[1] = event.getY();

        layoutTransitionMatrix.mapPoints(childTouchPoint, touchPoint);
        event.setLocation(childTouchPoint[0], childTouchPoint[1]);
        return super.dispatchTouchEvent(event);
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new RotateLayout.LayoutParams(getContext(), attrs);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams layoutParams) {
        return layoutParams instanceof RotateLayout.LayoutParams;
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams layoutParams) {
        return new RotateLayout.LayoutParams(layoutParams);
    }

    private View view;
    private int angle;

    private final Matrix layoutTransitionMatrix = new Matrix();

    private final Rect viewRectRotated = new Rect();

    private final RectF layoutRectF = new RectF();
    private final RectF layoutRectFRotated = new RectF();

    private final float[] touchPoint = new float[2];
    private final float[] childTouchPoint = new float[2];

    private boolean angleChanged = true;

}

attrs.xml (добавить этот файл в папку res / values)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="RotateLayout_Layout">
        <attr name="layout_angle" format="integer"  />
    </declare-styleable>

</resources>

Пример использования:

<com.you.package.name.RotateLayout
    xmlns:app="http://schemas.android.com/apk/res/com.you.package.name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_angle="-90"
        android:text="Rotated Button"/>
</com.you.package.name.RotateLayout>
...