简体   繁体   English

放大/缩小整个页面布局

[英]Zoom in/out the whole page layout

I am trying to write code for zoom in/out the whole page/screen of the app. 我正在尝试编写代码以放大/缩小应用程序的整个页面/屏幕。 I was given this link 给我这个链接

Android - zoom in/out RelativeLayout with spread/pinch Android-使用展开/捏放大/缩小RelativeLayout

but it's really difficult for a beginner to understand all the procedures to follow. 但是对于初学者来说,要理解所有遵循的程序确实非常困难。

If someone can help and provide clearer explanation on this topic, I and other beginners will surely appreciate it. 如果有人可以提供帮助并提供有关此主题的更清晰的说明,我和其他初学者肯定会感激的。

So far I have set MainActivity , AnswerActivity and Fragments . 到目前为止,我已经设置了MainActivityAnswerActivityFragments

First, lets start simple. 首先,让我们从简单开始。 Scaling is relatively easy. 缩放相对容易。 (this code is not used in the further examples): (此代码在其他示例中未使用):

    TextView rootView;
    rootView.setScaleX(sx);
    rootView.setScaleY(sx);

sx and sy is scale[X/Y] sxsy是scale [X / Y]

That is the fundamentals of scaling. 这就是扩展的基础。 Now we go to the hard part: Pinch zoom. 现在我们进入最困难的部分:捏缩放。 this requires user input in the form of touch events. 这要求用户以触摸事件的形式输入。

Start by setting an onTouchListener if you cannot use onTouchEvent for the root view. 如果无法将onTouchEvent用于根视图,请首先设置onTouchListener。 (I will not show this part) (我不会显示这部分)

Before you even start, declare a float called scaleFactor: 在开始之前,请声明一个称为scaleFactor的浮点数:

[ANY-ACCESS-MODIFIER] long scaleFactor = 1f;

First, we need a ScaleGestureListener. 首先,我们需要一个ScaleGestureListener。 This can be a nested class if wanted: 如果需要,可以是一个嵌套类:

class Scaler extends ScaleGestureDetector {
    public Scaler(Context context, OnScaleGestureListener listener) {
        super(context, listener);
    }

    @Override
    public float getScaleFactor() {//Leave this method empty.
        return super.getScaleFactor();
    }
}

Secondly we need the OnScaleGestureListener: 其次,我们需要OnScaleGestureListener:

class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener{

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scaleFactor *= detector.getScaleFactor();

        if(scaleFactor > 2) scaleFactor = 2;//Limit to your liking
        else if(scaleFactor < 0.3f) scaleFactor = 0.3f;//Limit to your liking
        scaleFactor = (scaleFactor * 100) / 100;//jitter-protection
        //scaleMatrix.setScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());//This is for usage with a Matrix: Good for canvas and other areas where this is usable. This is from my own scaling code, so I keep the matrix around in this example in case it is needed
        tv.setScaleX(scaleFactor);
        tv.setScaleY(scaleFactor);
        tv.setPivotX(detector.getFocusX());
        tv.setPivotY(detector.getFocusY());
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {return true;}

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {}
}

Now, this is where it splits in two. 现在,这是一分为二的地方。 If possible, use onTouchEvent(MotionEvent ev) . 如果可能,请使用onTouchEvent(MotionEvent ev) If you cannot use this method(when you add @Override above it it shows an error) you have to use onTouchListener instead. 如果您不能使用此方法(在上面添加@Override时显示错误),则必须改用onTouchListener。 set it on the TextView( tv.setOnTouchListener(this); . Make sure the class implements OnTouchListener) 在TextView上设置它( tv.setOnTouchListener(this);确保该类实现OnTouchListener)

Now, whatever method you picked, MAKE SURE IT RETURNS true ! 现在,无论选择哪种方法,都要确保它返回true

This code should work in both methods, and it isn't limited to a specific method: 这段代码应在两种方法中均有效,并且不仅限于特定方法:

(ev is MotionEvent) (ev是MotionEvent)

    int pointers = ev.getPointerCount();

    if(pointers == 2) {

        zoom = true;
        s.onTouchEvent(ev);//pass original motionevent(unscaled) to zoom

    }

Now, the base code is in place. 现在,基本代码已经准备就绪。 Now we need to create the instance for s : 现在,我们需要创建一个实例s

Globally declare: 全局声明:

private Scaler s;
private ScaleListener listener;

and where you inflate the layout: 以及您在布局中的位置:

listener = new ScaleListener();
s = new Scaler(c, listener);//c is a context. 

Now, assuming all the components are in place you have a functioning zoom-in/out system. 现在,假设所有组件均已安装到位,您将拥有一个正常运行的放大/缩小系统。 Please note that this does not cover scrolling on the zoomed view. 请注意,这不包括在缩放视图上滚动。 You have to create an offsetX/Y variable, and take input when there is one pointer and check how far a distance you want to move. 您必须创建一个offsetX / Y变量,并在有一个指针的情况下进行输入,并检查要移动的距离。

Using a TextView and touch events, you can use #setScrollX or #setScrollY along with an offset to set the new, scrolled position. 使用TextView和touch事件,可以将#setScrollX或#setScrollY以及偏移量与新的滚动位置一起使用。

It may though be easier to create your own, custom text view. 创建您自己的自定义文本视图可能会更容易。 You do this by creating a new class and making it extend TextView. 为此,您可以创建一个新类并使其扩展TextView。 Then you put modifications as you want into there. 然后,您可以根据需要在其中进行修改。 This would allow you to add zoom and such into the custom TextView. 这将允许您将缩放等添加到自定义TextView中。 This is though a prefered way to do it if you have multiple textviews in a single class or you have multiple activities with a zoomable and scrollable textview. 如果您在一个班级中拥有多个文本视图,或者您拥有多个具有可缩放和可滚动文本视图的活动,则这是首选的方法。


EDIT: Custom textview 编辑:自定义textview

Sadly, not a lot of the integrated tools does nto work. 可悲的是,并不是很多集成工具都无法正常工作。 android:scrollbars on a textview doesn't work for an instance. textview上的android:scrollbars不适用于实例。 So first the TextView has to have a ScrolLView around it: 因此,首先,TextView必须具有一个ScrolLView:

<ScrollView android:id="@+id/textScroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.package.ZoomableTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Some hfndusijhgn hgnm hnixjkgbhn fvb uynfv bunfg vbuygn buy hgnyu gnui h  uh nuioiogfej uhud\nfhbnikjhgnuieskhg nmuimjhbnguijhgne \nfuyh ghfuisdghbuisjhgnuie dgjh\nifgb dsauingfbehja kbfiuej ksghbisdjkg nbhni\ngfdfjgdfh hdfh sdfhg sh "/>

</ScrollView>

And ZoomableTextView: 和ZoomableTextView:

You need this dependency first: 您首先需要此依赖项:

compile 'com.android.support:appcompat-v7:25.3.1'

This is to get the AppCompat library so the TextView can use new features while maintaining support for earlier versions. 这是为了获得AppCompat库,以便TextView可以使用新功能,同时保持对早期版本的支持。 now for the class: 现在上课:

public class ZoomableTextView extends AppCompatTextView/*This is why the AppCompat dependency is needed*/ {
    private float textSize,
            textScale;
    private Scaler s;
    private ScaleListener listener;
    public ZoomableTextView(Context context) {
        super(context);
        init();
    }

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

    public ZoomableTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init(){
        listener = new ScaleListener();
        s = new Scaler(getContext(), listener);
        textSize = getTextSize();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        super.onTouchEvent(ev);
        if(ev.getPointerCount() == 2){
            s.onTouchEvent(ev);
        }
        return true;
    }

    class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener{

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            textScale *= detector.getScaleFactor();

            if(textScale > 2) textScale = 2;//Limit to your liking
            else if(textScale < 0.3f) textScale = 0.3f;//Limit to your liking
            textScale = (textScale * 100) / 100;//jitter-protection
            if(textScale < 0.3f) textScale = 0.3f;
            if(textScale > 2) textScale = 2;

            setTextSize(textSize * textScale);
            setPivotX(detector.getFocusX());
            setPivotY(detector.getFocusY());
            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {return true;}

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {}
    }

    class Scaler extends ScaleGestureDetector {
        public Scaler(Context context, OnScaleGestureListener listener) {
            super(context, listener);
        }

        @Override
        public float getScaleFactor() {//Leave this method empty.
            return super.getScaleFactor();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM