Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 746
Zubair Ahmed Avatar asked Jan 27 '16 08:01

Zubair Ahmed


1 Answers

  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!

like image 198
Konstantin Loginov Avatar answered Sep 27 '22 01:09

Konstantin Loginov