从右或向左增加LinearLayout宽度 [英] Increase LinearLayout width from either right or left

查看:75
本文介绍了从右或向左增加LinearLayout宽度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个LinearLayout,它位于屏幕中央.它的宽度小于屏幕宽度.有两个按钮:向右箭头和向左箭头.当用户按下相关按钮时,布局应从相关侧面增加其宽度.另一端应保持在该位置.

I have a LinearLayout which is centered on the screen. It has a width less than the screen width. There are two buttons: Right-Arrow and Left-Arrow. When the user presses the relevant button, the layout should increase its width from the relevant side. The other side should keep its position there.

现在,设置宽度可以从两侧平等地增加布局.布局需要首先居中,并且必须通过用户的输入从任一侧扩展.(用例是查找图像的相关部分的宽度,该图像的左右两侧具有不相等的边界,因此用户必须使用我的技术对其进行标记.)

Right now setting the width increases the layout from both sides equally. The layout needs to be initially centered and it has to expand from either side by user's input. (Use case is to find the width of relevant part of an image whose right and left sides have unequal borders, so the user has to mark them using my technique).

我正在使用以下方法来增加宽度,但是它具有上述行为.

I am using following to increase width but it has the behaviour described above.

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) 
                                      llCropOverlay.getLayoutParams();
params.width = params.width + 1;

PS:此功能自早期开始就在Tasker应用程序中实现;所以有可能.

PS: This functionality was implemented in Tasker app since its early days; so it is possible.

这是布局.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:gravity="top"
            android:layout_gravity="top"
            android:id="@+id/iv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="visible" />

        <LinearLayout
            android:id="@+id/llRightLeft"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center">

            <Button
                android:id="@+id/bLeft"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="LEFT" />

            <Button
                android:id="@+id/bRight"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="RIGHT" />
        </LinearLayout>


        <LinearLayout
            android:layout_gravity="center_horizontal"
            android:id="@+id/llCropOverlay"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:background="@color/colorCropOverlay"
            android:orientation="vertical" />
    </FrameLayout>
</LinearLayout>

应调整最后一个LinearLayout(llCropOverlay)的大小.请注意,在使用按钮大小调整之前,我正在以编程方式将宽度更改为300,这样我就可以测试按钮是否正常工作.

The last LinearLayout (llCropOverlay) should be resized. Note that I am programatically changing the width to 300 before using resizing the buttons so I can test if the buttons are working.

推荐答案

我找到了一个几乎完美的解决方案(有时一个像素令人讨厌的问题-任何建议都将得到赞赏).

I have found an almost perfect solution (there is sometimes a problem with one pixel which is annoying - any suggestions will be appreciated).

为此,我们需要设置一些变量.首先,必须找到并标识名为llCropOverlay的LinearLayout.这是它的xml:

For this, we need some variables set up. Firstly, the LinearLayout called llCropOverlay must be found and identified. Here is its xml:

        <LinearLayout
            android:layout_gravity="center_horizontal"
            android:id="@+id/llCropOverlay"
            android:layout_width="200dp"
            android:layout_height="150dp"
            android:background="@color/colorCropOverlay"
            android:orientation="vertical" />

现在,在允许用户进行交互之前,我们需要找到llCropOverlay的原始位置.因此,请在OnCreate()中使用它:

Now before allowing user to interact we need to find the original position of the llCropOverlay. So use this in OnCreate():

llCropOverlay.post(new Runnable() {
            @Override
            public void run() {
                orgX = llCropOverlay.getX();
            }
        });

现在设置所有按钮,并在这些按钮上设置setOnTouchListener().然后,当调用侦听器时,请通过以下方法传递被触摸的按钮.使用Handler和postDelayed()继续调用此方法,直到按下按钮为止.或调用一次以按一个像素行/列调整大小.

Now set up all the buttons and set a setOnTouchListener() on these buttons. Then when the listener is called, pass the touched button in the following method. Use a Handler and postDelayed() to keep calling this method till the button is pressed. Or call it once to resize by one pixel row/column.

void handleTouchOrClick(View view) {
    ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) 
               llCropOverlay.getLayoutParams();

    switch (view.getId()) {
        case R.id.bUp:
            params.height = params.height - 1;
            break;
        case R.id.bDown:
            params.height = params.height + 1;
            break;
        case R.id.bRight:
            params.width = params.width + 1;
            llCropOverlay.post(new Runnable() {
                @Override
                public void run() {
                    llCropOverlay.setX(orgX);
                }
            });
            break;
        case R.id.bRightContract:
            params.width = params.width - 1;
            llCropOverlay.post(new Runnable() {
                @Override
                public void run() {
                    llCropOverlay.setX(orgX);
                }
            });
            break;
        case R.id.bLeft:
            params.width = params.width + 1;
            orgX--;
            llCropOverlay.post(new Runnable() {
                @Override
                public void run() {
                    llCropOverlay.setX(orgX);
                }
            });
            break;
        case R.id.bLeftContract:
            params.width = params.width - 1;
            orgX++;
            llCropOverlay.post(new Runnable() {
                @Override
                public void run() {
                    llCropOverlay.setX(orgX);
                }
            });
            break;
    }
    llCropOverlay.setLayoutParams(params);
}

现在这是我们实际调整图像大小的方法:为了方便用户,我分两步对其进行裁剪.

Now here's how we actually resize the image: For ease of users I am cropping it in two steps.

从两边裁切:

            ViewGroup.MarginLayoutParams params =
     (ViewGroup.MarginLayoutParams) llCropOverlay.getLayoutParams();

                    float eventX = params.width;
                    float eventY = 0;
                    float[] eventXY = new float[]{eventX, eventY};

                    Matrix invertMatrix = new Matrix();
                    imageView.getImageMatrix().invert(invertMatrix);

                    invertMatrix.mapPoints(eventXY);
                    int x = Integer.valueOf((int) eventXY[0]);
                    int y = Integer.valueOf((int) eventXY[1]);

                    int height = params.height;
                    while (height * 3 > originalBitmap.getHeight()) {
                        height = height - 10;
                    }
                    croppedBitmapByWidth = Bitmap.createBitmap(originalBitmap, (int) orgX, 0,
                            x, height);
                    imageView.setImageBitmap(croppedBitmapByWidth);    

从底部裁剪:

                    float eventX2 = 0;
                    float eventY2 = params.height;
                    float[] eventXY2 = new float[]{eventX2, eventY2};

                    Matrix invertMatrix2 = new Matrix();
                    imageView.getImageMatrix().invert(invertMatrix2);

                    invertMatrix2.mapPoints(eventXY2);
                    int x2 = Integer.valueOf((int) eventXY2[0]);
                    int y2 = Integer.valueOf((int) eventXY2[1]);

                    croppedBitmapByHeight = Bitmap.createBitmap(croppedBitmapByWidth, 0, 0, 
                                 croppedBitmapByWidth.getWidth(), y2);
                    imageView.setImageBitmap(croppedBitmapByHeight);

这篇关于从右或向左增加LinearLayout宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆