How to hold and drag (re-position) a layout along with its associated layouts in android
Asked Answered
H

1

6

I am making an android app. In which I have a scenario. First watch screen shot below so any one come here to answer has some clear picture that what I want.

enter image description here

Scenario: Activity having map below navigation bar, a RelativeLayout (Red background) in center, a ListView below Red RelativeLayout

What I want: I want to drag or re-position (whatever the term may be used by others) Red RelativeLayout by holding my finger on it and move up and down on the screen along with listview below should also move with this layout

Code I tried:

xml layout

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

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/fifty_five_dp"
            android:id="@+id/topBar"
            android:background="@color/bg_color" >

            <Button
                android:id="@+id/button_menu"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="4dp"
                android:background="@drawable/list_btn"
                android:onClick="toggleMenu" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="Watchover"
                android:textColor="@android:color/white"
                android:textSize="@dimen/eighteen_sp"
                android:textStyle="bold" />
        </RelativeLayout>

        <!-- This is where fragment will show up -->

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/topBar"
            android:id="@+id/root"
            android:background="@android:color/white" >

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white" >

                <fragment
                    android:id="@+id/map"
                   android:name="com.google.android.gms.maps.SupportMapFragment"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_above="@+id/greenBarImage" />

                <RelativeLayout
                    android:id="@+id/redLayout"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/forty_dp"
                    android:layout_centerVertical="true"
                    android:background="@color/btn_color" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:text="Fences Info"
                        android:textColor="@android:color/white"
                        android:textSize="@dimen/sixteen_sp" />

                    <Button
                        android:id="@+id/btn_drag"
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:layout_alignParentRight="true"
                        android:layout_centerVertical="true"
                        android:layout_marginRight="4dp"
                        android:background="@drawable/list_btn"
                        android:onClick="toggleMenu"
                        android:visibility="gone" />
                </RelativeLayout>

                <ListView
                    android:id="@+id/list_devices"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/greenBarImage"
                    android:padding="@dimen/five_dp"
                    android:scrollbars="none" />
            </RelativeLayout>
        </FrameLayout>

    </RelativeLayout>

Java code:

public class MyActivity extends FragmentActivity implements OnTouchListener
{
    private int _xDelta;
    private int _yDelta;
    RelativeLayout redLayout;

    FrameLayout rootLayout;

    ListView devicesList;

    @Override
    protected void onCreate(Bundle arg0) 
    {
        super.onCreate(arg0);

        setContentView(R.layout.main_screen);

        devicesList = (ListView) findViewById(R.id.list_devices);

        rootLayout = (FrameLayout) findViewById(R.id.root);

        redLayout = (RelativeLayout) findViewById(R.id.redLayout);
        redLayout.setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) 
    {
        final int X = (int) event.getRawX();
        final int Y = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
            _xDelta = X - lParams.leftMargin;
            _yDelta = Y - lParams.topMargin;
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_POINTER_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
            layoutParams.leftMargin = X - _xDelta;
            layoutParams.topMargin = Y - _yDelta;
            layoutParams.rightMargin = -250;
            layoutParams.bottomMargin = -250;
            view.setLayoutParams(layoutParams);
            break;
        }
        rootLayout.invalidate();
        return true;
    }
}

Source for getting above code help here

I tried the code not getting desired result. When I drag the red RelativeLayout up and down, listview overlay on that layout and not adjusted as I want. Any type of help would be appreciated.

Honesty answered 27/1, 2016 at 8:46 Comment(0)
P
8
  1. Material way

    You can archive it(or, at least, very close to what you want) with CoordinatorLayout and keeping your map layout inside CollapsingToolbarLayout.

    Your layout can look like this:

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
    
            <!-- MAP -->
            <RelativeLayout
                ...
                app:layout_collapseMode="parallax">
                .....
            </RelativeLayout>
            <!-- Toolbar -->
            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />
    
        </android.support.design.widget.CollapsingToolbarLayout>
    
       <!-- This red thingy, if you need it -->
        <View
             android:layout_width="match_parent"
             android:layout_height=".."/>
    </android.support.design.widget.AppBarLayout>
    
    <!--List Of your content items -->
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    

    You can read more here Android Design Support Library and here Design Support Library (III): Coordinator Layout

  2. View.OnTouchListener way

    (This is the one you use)

    Idea is simple:

    • Set Map android:layout_above red separator & ListView - android:layout_below red separator
    • Once moving action done - translate separator respectively up or down and set proper top&bottom mangins

    Here's how it looks:

    enter image description here

        public class MainActivity extends AppCompatActivity  implements View.OnTouchListener {
            private int _yDelta;
            @Override
            protected void onCreate(Bundle arg0) {
                super.onCreate(arg0);
                setContentView(R.layout.activity_main);
                findViewById(R.id.separator).setOnTouchListener(this);
            }
    
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                final int Y = (int) event.getRawY();
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:
                        RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
                        _yDelta = Y - lParams.bottomMargin;
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        break;
                    case MotionEvent.ACTION_POINTER_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:
                        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
                        layoutParams.bottomMargin = (Y - _yDelta);
                        layoutParams.topMargin = -layoutParams.bottomMargin;
                        view.setLayoutParams(layoutParams);
                        view.animate().translationY(Y - _yDelta).setDuration(0);
                        break;
                }
                findViewById(R.id.root).invalidate();
                return true;
            }
        }
    

    And activity_main.xml:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/root">
        <View
            android:background="#AA0F00FF"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/separator"/>
        <View
            android:layout_below="@+id/separator"
            android:background="#AA0FF000"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <View
            android:background="#FF0000"
            android:layout_centerVertical="true"
            android:id="@+id/separator"
            android:layout_width="match_parent"
            android:layout_height="20dp" />
    </RelativeLayout>
    

I hope, it helps!

Philpot answered 29/1, 2016 at 11:42 Comment(12)
How to use these libraries in eclipse? As I am developing this app in eclipseHonesty
@ZubairAhmadKhan check this link: #26879303 and this: developer.android.com/tools/support-library/… (P.S. Android Studio 2.0 is so much better experience, than Eclipse. Just give it a try)Philpot
I know about Android Studio. For the time being I have not much time to shift from eclipse to Studio. I want to know is it possible to use these libraries in eclipse? If yes Kindly suggest me a way ThanksHonesty
@ZubairAhmadKhan I've already did - check links(especially first one) in my previous comment.Philpot
@ZubairAhmadKhan I've updated my answer with second solution, which doesn't require Support Libs. Enjoy!Philpot
@ZubairAhmadKhan Still developing in Eclipse, why are you doing this to yourself? :oMadame
@KonstantinLoginov Thanks for the answer. Sure I will try then comment :)Honesty
@KonstantinLoginov Your solution worked like a charm. Great answer thank you:). I run the app but there is a little issue in this I've noticed that when I tap and drag the Red Layout (seperator) towards the bottom then at one stage it disappears from the screen and no way to get it back same as when drag towards top can you suggest a fix for this?Honesty
@ZubairAhmadKhan You're more than welcome! Great, that it works for you. I'd suggest to get Root layout height, Y-position of the Red layout and every time you do translation, check if new Y-value is out of the screen or not. If it's getting too big or negative (when you drag it on top) - avoid doing translation/translate back to the viewport, etc.Philpot
I debug the code and tried to figure it out. When moving towards top. Its giving root_layout height = 1683, total screen height = 1776, Y-Delta value decreasing from 1100 (approx when at center) to 1084 (approx when reached to the top most just below navigation bar)Honesty
@ZubairAhmadKhan just use Math functions there, max or min. Fairly easy.Philpot
@KonstantinLoginov I did it Thank you so much. You deserve my bounty and vote appreciate your helpHonesty

© 2022 - 2024 — McMap. All rights reserved.