Android LinearLayout with drag and drop to reorder.

Overview

DragLinearLayout

Dragging and swapping children views.

An Android LinearLayout that supports draggable and swappable child Views.

Why?

Why bother doing drag & swap in a LinearLayout when there are so many solutions for ListView?

  1. Simplicity - no need for ListAdapters. By default, works like a LinearLayout.
  2. Flexibility - supports heterogeneous, selectively draggable (or not draggable), children.
  3. Portability - can be used in any layout, e.g. as a child in a ScrollView container.

Usage

Add it to your project using Gradle:

compile 'com.jmedeisis:draglinearlayout:1.1.0'

The DragLinearLayout can be used in place of any LinearLayout. However, by default, children will not be draggable. To set an existing View as draggable, use DragLinearLayout#setViewDraggable(View, View), passing in the child View and a (non-null!) View that will act as the handle for dragging it (this can be the View itself).

XML layout file:

<com.jmedeisis.draglinearlayout.DragLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/text" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:scaleType="centerCrop"
        android:src="@drawable/image"/>

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_text"/>
        
</com.jmedeisis.draglinearlayout.DragLinearLayout>

Enabling drag & swap for all child views:

DragLinearLayout dragLinearLayout = (DragLinearLayout) findViewById(R.id.container);
for(int i = 0; i < dragLinearLayout.getChildCount(); i++){
    View child = dragLinearLayout.getChildAt(i);
    // the child will act as its own drag handle
    dragLinearLayout.setViewDraggable(child, child);
}

Use #addDragView(View, View),#addDragView(View, View, int) and #removeDragView(View) to manage draggable children dynamically:

final View view = View.inflate(context, R.layout.view_layout, null);
dragLinearLayout.addDragView(view, view.findViewById(R.id.view_drag_handle));

// ..

dragLinearLayout.removeDragView(view);

Attach an OnViewSwapListener with #setOnViewSwapListener(OnViewSwapListener) to detect changes to the ordering of child Views:

dragLinearLayout.setOnViewSwapListener(new DragLinearLayout.OnViewSwapListener() {
    @Override
    public void onSwap(View firstView, int firstPosition,
            View secondView, int secondPosition) {
        // update data, etc..
    }
});

When placing the DragLinearLayout inside a ScrollView, call #setContainerScrollView(ScrollView) to enable the user to scroll while dragging a child view.

For best visual results, use children that have opaque backgrounds. Furthermore, do not use horizontal padding for the DragLinearLayout; instead, let children apply their own horizontal padding.

Refer to the included sample activity project for a demonstration of the above usage techniques and more.

Limitations

  • Supports only the LinearLayout#VERTICAL orientation.

License

This project is licensed under the terms of the MIT license. You may find a copy of the license in the included LICENSE file.

Comments
  • Adding to project using gradle doesn't work

    Adding to project using gradle doesn't work

    Hi,

    I'm trying to use your project using gradle.

    However using compile 'com.jmedeisis:draglinearlayout:1.1.0' in gradle doesn't work. Is that normal? Thanks in advance.

    EDIT: my bad, succeed with adding allprojects { repositories { jcenter() } }

    opened by Virthuss 16
  • Make it work for LinearLayout#HORIZONTAL as well.

    Make it work for LinearLayout#HORIZONTAL as well.

    Hey! Awesome project! I'm working on this issue. It's mostly just adding a bunch of switch statements :/. Is this a thing you want? https://github.com/cmcneil/DragLinearLayout

    opened by cmcneil 6
  • custom onDragStopListener

    custom onDragStopListener

    Is there a way to get a onDragStopListener? I need to detect when the view is placed in the right position? because if I use setOnViewSwapListener(); the order of the views in the draglinearlayout is not committed.

    if someone changes the order of the views. I need to read the correct order of the views so I can handle code for each view.

    view1.print("1"); view2.print("2"); view3.print("3");

    after changing the order 2 becomes 3 and 3 becomes 2. this is what I need to call

    view1.print("1"); view3.print("3"); view2.print("2");

    How can I do this?

    opened by vanlooverenkoen 5
  • Fix for dragg in scroll view

    Fix for dragg in scroll view

    Thanks to that we don't have to slowly move finger to dragg element.

    When we move really fast finger scroll view will take this touch and drag will be canceled.

    opened by gelldur 4
  • Get the Child position

    Get the Child position

    Hi there, I wonder say first of all thank you for your amazing job, is really useful. My issue is about, how can I get the child position after drag and drop few times the picture inside the container (Custom View)?

    I need to passing the uri of each image after the user have swapped all the pics to another activity, but I couldn't find a solution.

    Could you help me please.

    Thanks for you help

    opened by alexiscanny 4
  • Importing project by using the zip downloaded or cloned from github?

    Importing project by using the zip downloaded or cloned from github?

    Hi guys,

    So I'm opening a new issue as asked in the last one.

    Using android studio at the moment, trying to use your library without using compile 'com.jmedeisis:draglinearlayout:1.1.0' in the gradle file but by importing the zip file downloaded or cloned from github is not working.

    When included, the project make gradle to send an error : Error:Cannot access first() element from an empty List. I can however open, build and run your project in a different android studio window, but importing it is still impossible. In my case this is preventing me to import meesec's fork as well. I'm using the build tools version 23 and am targeting the devices using API 15 or above.

    opened by Virthuss 4
  • Can i get all added child position after swap and drag ?

    Can i get all added child position after swap and drag ?

    Hi @justasm

    it's a great work you have done, Thanks You.

    I have added 4 ImageView in DragLinearLayout then after add setViewDraggable and also set setOnViewSwapListener in my App

    My question is when i drag and swipe child view can i get Last Changed position with tag?

    Thanks.

    opened by GauravCreed 3
  • Unable to resolve depenency

    Unable to resolve depenency

    Hi!

    Your implementation seams to be quite simple to put in place and I'd love to give it a try. However, even though I have jcenter in my project's build.gradle, and after adding compile 'com.jmedeisis:draglinearlayout:1.1.0' into my app's build.gradle, I get the following error:

    Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.jmedeisis:draglinearlayout:1.1.0

    Actually, I get many Unable to resolve dependency for errors while trying to sync my build.gradle

    Has it been changed from jcenter and now uses another repository? I have the google one added as well.

    opened by carlos-mg89 3
  • bugfix: DragLinearLayout animation conflicts with LayoutTransition

    bugfix: DragLinearLayout animation conflicts with LayoutTransition

    An exception is thrown when add android:animateLayoutChanges="true" to DragLinearLayout:

    java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
                at android.view.ViewGroup.addViewInner(ViewGroup.java:3562)
                at android.view.ViewGroup.addView(ViewGroup.java:3415)
                at android.view.ViewGroup.addView(ViewGroup.java:3360)
                at com.jmedeisis.draglinearlayout.DragLinearLayout.onDrag(DragLinearLayout.java:447)
                at com.jmedeisis.draglinearlayout.DragLinearLayout.onTouchEvent(DragLinearLayout.java:661)
                at android.view.View.dispatchTouchEvent(View.java:7714)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
    
    opened by xuxucode 3
  • Support drag and drop  Listview or child View's  elements

    Support drag and drop Listview or child View's elements

    Hi I'm using your library.Everything working perfect,but i have one question.Is it a possible to use this librare in Listview,I mean BaseAdapter, or if i add childView programmatically? I tried SimpleAdapter and BaseAdapter,but i still can't drag and drop in listviews. thanks

    opened by Bekakk 2
  • Can't drag layout child

    Can't drag layout child

    Hi, I'm trying to solve this problem but I don't understand why it occurs. My aim is to save buttons's positions in SharedPreferences in order to restore their position when the App is launched the next time. When SharedPreferences are empty, the drag and drop feature works fine. Instead, when I launch again the App, after the code loads the buttons's indexes, the drag and drop feature get stuck. I can't drag buttons. It's like the buttons are not set as draggable. Any solution? Thanks.

    
    @SuppressLint("SetTextI18n, CommitPrefEdits")
    public class MainActivity extends AppCompatActivity {
    
        SharedPreferences SP;
        SharedPreferences.Editor mEditor;
        DragLinearLayout dragLinearLayout;
        Button mButton, mButton2, mButton3, mButton4;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
            mEditor = SP.edit();
    
            dragLinearLayout = (DragLinearLayout) findViewById(R.id.container);
    
            mButton = (Button) findViewById(R.id.button);
            mButton2 = (Button) findViewById(R.id.button2);
            mButton3 = (Button) findViewById(R.id.button3);
            mButton4 = (Button) findViewById(R.id.button4);
    
            for(int mInt = 0; mInt < dragLinearLayout.getChildCount(); mInt++) {
                View mChild = dragLinearLayout.getChildAt(mInt);
                dragLinearLayout.setViewDraggable(mChild, mChild);
                dragLinearLayout.removeView(mChild);
                switch (mChild.getId()) {
                    case R.id.button:
                        dragLinearLayout.addDragView(mButton, mButton, SP.getInt(Integer.toString(mButton.getId()), 0));
                        break;
                    case R.id.button2:
                        dragLinearLayout.addDragView(mButton2, mButton2, SP.getInt(Integer.toString(mButton2.getId()), 1));
                        break;
                    case R.id.button3:
                        dragLinearLayout.addDragView(mButton3, mButton3, SP.getInt(Integer.toString(mButton3.getId()), 2));
                        break;
                    case R.id.button4:
                        dragLinearLayout.addDragView(mButton4, mButton4, SP.getInt(Integer.toString(mButton4.getId()), 3));
                        break;
                }
            }
    
            dragLinearLayout.setOnViewSwapListener(new DragLinearLayout.OnViewSwapListener() {
                @Override
                public void onSwap(View firstView, int firstPosition, View secondView, int secondPosition) {
                    mEditor.putInt(Integer.toString(firstView.getId()), secondPosition).apply();
                    mEditor.putInt(Integer.toString(secondView.getId()), firstPosition).apply();
                }
            });
    
        }
    }
    
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <com.jmedeisis.draglinearlayout.DragLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"
        android:paddingTop="20dp"
        android:gravity="center_horizontal">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 1"
            android:id="@+id/button"
            android:layout_alignParentTop="true" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 2"
            android:id="@+id/button2"
            android:layout_below="@+id/button"
            android:layout_centerHorizontal="true" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 3"
            android:id="@+id/button3"
            android:layout_below="@+id/button2" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 4"
            android:id="@+id/button4" />
    </com.jmedeisis.draglinearlayout.DragLinearLayout>
    
    
    opened by goldmont 2
  • How to scroll without dragging when using it inside a ScrollView?

    How to scroll without dragging when using it inside a ScrollView?

    It almost seems impossible to scroll up/down if this is nested in a scroll view? Is it just the nature of this library or is there a way to achieve scrollability and dragability at the same time?

    opened by nicoqueijo 1
  • very poor drag, or it barely can drag the images

    very poor drag, or it barely can drag the images

    Hi

    Edit :

    The issue is ( The DragLinearLayout doesn't work with ScrollView )

    I am adding ImageViews programatically, but the images can barely drag. it require very long press, sometimes it works and sometimes doesn't.

    this is the adding function

    Java

    private void appendImageToLinearLayout(DragLinearLayout layout,
                                           ParseFile parseFileImage,
                                           int w, int h,
                                           boolean fullWidth,
                                           boolean isPostImage,
                                           final int position)
            throws ParseException, IOException {
    
        ImageView imageView= new ImageView(this);
        //imageView.setBackgroundResource(R.drawable.ic_action_search);
        imageView.setImageBitmap(
    
                ImageTools.
                        getBitmapFromUri(Uri.fromFile(
                                parseFileImage.getFile()),
                                this, fullWidth
                        )
        );
    
        // params
        //DragLinearLayout.LayoutParams viewParamsCenter =
                new DragLinearLayout.LayoutParams(
                        w,
                        h);
        //viewParamsCenter.gravity = Gravity.CENTER_HORIZONTAL | Gravity.RIGHT;
    
        //imageView.setLayoutParams(viewParamsCenter);
        imageView.setId(position);
        imageView.setContentDescription(imageList.get(position).getObjectId());
        layout.addDragView(imageView, imageView);
    
        //layout.setViewDraggable(imageView, imageView);
    
        if(isPostImage){
    
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //showImageFullScreen(position);
                    Toast.makeText(EditPostActivity.this, "clicked " + v.getId(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
    

    XML

    <ScrollView
        android:id="@+id/llCanvusContainer"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        android:background="@android:color/white"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/switchIsPublic">
    
        <com.jmedeisis.draglinearlayout.DragLinearLayout
            android:id="@+id/llCanvus"
            style="@style/Gallery19crollbarStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/switchIsPublic" />
    
    </ScrollView>
    

    The images show correctly, but the dragging doesn't work correctly.

    #note: the drag and drop works fine when I remove the ScrollView

    opened by hatimmakki 0
  • Add Ability to Disable View Draggability

    Add Ability to Disable View Draggability

    It would be nice to be able to make views which are currently draggable non-draggable. Maybe like this:

    Current: public void setViewDraggable(View child, View dragHandle) Possibe: public void setViewDraggable(View child, View dragHandle, boolean isDraggable)

    opened by DanStout 1
  • Handle DragLinearLayout not the only child of the ScrollView

    Handle DragLinearLayout not the only child of the ScrollView

    The scrolling goes a bit crazy when the DragLinearLayout is nested within a few layouts within the ScrollView, rather than the LinearLayout being the child of a ScrollView.

    This fixes the problem by getting the top of the LinearLayout relative to the ScrollView, rather than just the top relative to the DragLinearLayout's parent.

    opened by jsonfry 0
Releases(v1.1.0)
Owner
Justas Medeišis
Justas Medeišis
null 2.4k Dec 30, 2022
TileView is a subclass of android.view.ViewGroup that asynchronously displays, pans and zooms tile-based images. Plugins are available for features like markers, hotspots, and path drawing.

This project isn't maintained anymore. It is now recommended to use https://github.com/peterLaurence/MapView. MapView is maintained by Peter, one of o

Mike Dunn 1.5k Nov 21, 2022
This library provides a simple way to add a draggable sliding up panel (popularized by Google Music and Google Maps) to your Android application. Brought to you by Umano.

Note: we are not actively responding to issues right now. If you find a bug, please submit a PR. Android Sliding Up Panel This library provides a simp

Umano: News Read To You 9.4k Dec 31, 2022
Android Sample Project with Material Design and Toolbar.

AndroidMaterialDesignToolbar -- PROJECT IS NOT SUPPORTED Android Sample Project with Material Design and Toolbar. Project use Appcompat library for ma

kemal selim tekinarslan 713 Nov 11, 2022
Easy, flexible and powerful Swipe Layout for Android

SwipeRevealLayout A layout that you can swipe/slide to show another layout. Demo Overview Drag mode Drag mode normal: Drag mode same_level: Features F

Chau Thai 1.5k Jan 4, 2023
BlurView - A very fast and dynamic blur layout for Android

BlurView - A very fast and dynamic blur layout for Android

null 16 Jul 11, 2022
ConstraintLayout is an Android layout component which allows you to position and size widgets in a flexible way

ConstraintLayout is a layout manager for Android which allows you to position and size widgets in a flexible way. It's available for both the Android view system and Jetpack Compose.

Android Jetpack 970 Jan 6, 2023
Implementation of ExpandableListview with custom header and custom content.

ExpandableLayout ExpandableLayout provides an easy way to create a view called header with an expandable view. Both view are external layout to allow

Robin Chutaux 1.6k Dec 12, 2022
[Archived] Highlight the best bits of your app to users quickly, simply, and cool...ly

ShowcaseView The ShowcaseView (SCV) library is designed to highlight and showcase specific parts of apps to the user with a distinctive and attractive

Alex Curran 5.6k Dec 16, 2022
VoronoiView is a view (ViewGroup) that allows you to add and display views inside Voronoi diagram regions.

Vorolay VoronoiView is a view (ViewGroup) that allows you to add and display views inside Voronoi diagram regions. [Voronoi diagram] (https://en.wikip

Daniil Jurjev 918 Dec 4, 2022
Navigation Drawer Activity with material design style and simplified methods

MaterialNavigationDrawer Navigation Drawer Activity with material design style and simplified methods       It requires 10+ API and android support v7

Fabio Biola 1.6k Dec 30, 2022
A beautiful leanback port for Smartphones and Tablets

MaterialLeanBack A beautiful leanback port for Smartphones and Tablets Sample Usage In your layout <com.github.florent37.materialleanback.MaterialLean

Florent CHAMPIGNY 739 Aug 2, 2022
A layout that hide the header when the body is scrolled down and reveal it when the header is scrolled up

AndroidAutoHideHeader A layout that hide the header when the body is scrolled down and reveal it when the header is scrolled up Demo Import it ! In yo

Vadim Caen 48 Apr 22, 2022
You don’t want your apps look and feel boring, do you? Add some bubbles!

#BubbleAnimationLayout Say hello to Bubble Animation Layout for Android by Cleveroad You don’t want your apps look and feel boring, do you? Add some b

Cleveroad 576 Nov 23, 2022
This assignment gives you basically a post list and its detail with comments.🚀

Android Assignment ?? Description This assignment gives you basically a post list and its detail with comments. ?? Features Users can see random post

Okan AYDIN 31 Dec 20, 2022
A Playground repository to showcase UI's and transitions built using Motion Layout.

A collection of UI's built to showcase the capabilities of Motion Layout and Constraint Layout 2.0/2.1

Saurabh 163 Dec 22, 2022
Added support to modify text size and indicator width based on the original TabLayout.

XTabLayout——可修改选中项字体大小和指示器长度的TabLayout XTabLayout是基于design包中的TabLayout进行了功能的扩展,在保留原有功能的基础上,增加了修改选中项字体大小、修改指示器长度以及限制屏幕显示范围内显示的Tab个数。 集成步骤: 1.添加XTabLayo

Kennor 660 Dec 20, 2022
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube graphic component.

Draggable Panel DEPRECATED. This project is not maintained anymore. Draggable Panel is an Android library created to build a draggable user interface

Pedro Vicente Gómez Sánchez 3k Jan 5, 2023
Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your development.

Bubbles for Android Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your

Txus Ballesteros 1.5k Jan 2, 2023