justasm / draglinearlayout Goto Github PK
View Code? Open in Web Editor NEWAndroid LinearLayout with drag and drop to reorder.
License: MIT License
Android LinearLayout with drag and drop to reorder.
License: MIT License
Hi,
I have implemented your library in my App to edit buttons order in a scrollview.. It works fine but I haven't managed to save the new buttons order. Each time I restart the App, the default order is restored. Could you help me please? Thank you in advance!
The implementation of the DragLinearLayout works fine until I also implement Android's LayoutTransition.
I get this error:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
And I get runtime errors on these two methods in the DragLinearLayout class :
1. addView(draggedItem.view, switchPosition); //called in on drag
2. onDrag(deltaY); // called in the onTouchEvent override method.
I stopped it crashing by overriding onTouchEvent() in my implementing activity, and setting the setLayoutTransition parameter to null on the DraggerLinearLayout when the row is touched, then in the DragLinearLayout when onAnimaitonEnd is called, I call a method in my implementing activity and make the setLayoutTransition() parameter not null anymore.
But this causes some lag, and on the row you're dragging when you stop the drag and let it settle, it disappears for a second and then reappears.
Is there anyway to implement the LayoutTransition, or any other recommended techniques for using animations to add rows, and for animating the incrementally increasing size of the DragLinearLayout?
Thanks in advance.
Would be great to add the library simply adding a dependency :)
When you try to drag the first child of the layout a crash happens.
Stacktrace:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jmedeisis.draglinearlayout.DragLinearLayout$DraggableChild.endExistingAnimation()' on a null object reference
at com.jmedeisis.draglinearlayout.DragLinearLayout.startDetectingDrag(DragLinearLayout.java:348)
at com.jmedeisis.draglinearlayout.DragLinearLayout.access$2200(DragLinearLayout.java:40)
at com.jmedeisis.draglinearlayout.DragLinearLayout$DragHandleOnTouchListener.onTouch(DragLinearLayout.java:701)
Version 1.0.0 and 1.1.0
If the LinearLayout has animateLayoutChanges
set to true, dragging a child view causes
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:3880)
at android.view.ViewGroup.addView(ViewGroup.java:3733)
at android.view.ViewGroup.addView(ViewGroup.java:3678)
at com.jmedeisis.draglinearlayout.DragLinearLayout.onDrag(DragLinearLayout.java:442)
at com.jmedeisis.draglinearlayout.DragLinearLayout.onTouchEvent(DragLinearLayout.java:661)
I tested this in an empty test project with simple TextViews as the children, to make sure there is nothing else causing it.
For now I think you should add to the "limitations" section that it will not work with animateLayoutChanges
enabling drag on long click is not available and no callback method for ondragstop.
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
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.
Care needs to be taken if the user wishes nested Views to be drag handles.
Add a configurable attribute if old behavior is desired.
I cannot use your library for my custom layout in a draglinearlayout.
Here is my custome layout inflated several times:
<com.mypackage.CustomRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/stationlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/cornerbackground"
android:longClickable="true"
android:clickable="true"
android:focusable="true"
android:paddingBottom="10dp"
android:paddingRight="10dp">
And the scroll view containing the draglinear layout:
<ScrollView
android:id="@+id/scroller"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:orientation="vertical">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollcontentcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
Nothing happens then, like if the focus was stolen somewhere.
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
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
When the list is short (not scrollable) , it is easy to touch and drag thing around. However, when the list is so long I cannot make a drag. Most of the time, when I try to drag the whole screen is scrolled instead.
I look at your sample it presents no problems. I am confused right now.
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.
Temporary fix: ensure all draggable children are in a contiguous block in the layout. Have non-draggable items as the header and/or footer to the layout portion that contains the draggable items.
First thank you for making this library open source, it really helped me a lot when implementing the animation using native drag and drop API.
And I've found a small issue when reading the code in this library. On DragLinearLayout.java#L424, if switch view is being animated, the visual position will be View.getY() instead of View.getTop(), and using getY() can avoid the visual glitch that happens when the switch view is going back and forth midway in the animation. You can observe this behavior if you make the animation time larger, for example 1 second, and drag the item around another view up and down quickly.
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>
Any idea how to update this layout to support horizontal dragging as well? It could be really useful in case of tablets where the screen goes more horizontally than vertically.
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)
Hi
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
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();
}
});
}
}
<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
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?
Can you help me deal with swapping children programmatically ? the only solution i can find is to delete a view and add it to a position , but it's not a clean solution , i want it to be animated just like a simple drag animation.
Hi,
I want to load the layout (after drag) even after user has restarted his phone. Is this possible?
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?
Hi, I request you to update this library with the latest SDK
So, you can only drag views around by only touching them?
Can we drag the views only if we long click the views?
First, I appreciate your library. This is working like a charm.
However, I want to use this library to horizontal orientation.
Are you planning to support horizontal orientation in the near future?
Or, I would try it by myself. Then, could you give me some tips for that? (like if there is a big problem to do that, please let me know so that I could save some time)
Thanks.
Can you show some sample that doesn't inflate new layout? just using current layout, and pick some ID to allow draggable.
A dragged item that triggers a swap transition with the child above it and is then released close to its final position is momentarily overlapped by the transitioning child below it.
To prevent from being dragger under DragLinearLayout edges.
When I add compile 'com.jmedeisis:draglinearlayout:1.1.0' to Gradle and I run the App on Android 5 device, the app crash when try to load Retrofit2 (compile 'com.squareup.retrofit2:retrofit:2.3.0' AND compile 'com.squareup.retrofit2:converter-gson:2.3.0'). With Android 6 o + the Apps aren't crashing.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Could not find com.jmedeisis:draglinearlayout:2.1.1.
Searched in the following locations:
- https://dl.google.com/dl/android/maven2/com/jmedeisis/draglinearlayout/2.1.1/draglinearlayout-2.1.1.pom
- https://repo.maven.apache.org/maven2/com/jmedeisis/draglinearlayout/2.1.1/draglinearlayout-2.1.1.pom
- https://jitpack.io/com/jmedeisis/draglinearlayout/2.1.1/draglinearlayout-2.1.1.pom
Required by:
project :app
Awesome library,
i have a simple layout like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<com.jmedeisis.draglinearlayout.DragLinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/drag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#55000000">
<TextView
android:id="@+id/display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The Quick Brown Fox Jumped!!"
android:padding="15dp"/>
</LinearLayout>
</com.jmedeisis.draglinearlayout.DragLinearLayout>
</RelativeLayout>
The LinearLayout with id="drag" keeps snapping back to the top after i drag it.
How do i make it maintain its new position in the layout.
also it would be nice if there was a way to disable the snapping feature
Thanks
Is there a way to get a rounded shadow that matches my rounded view background?
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()
}
}
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.
I use a few relative layout inside draglinearlayout but Draglistener cant trigger . I cant dragging anything . Just textview or relative work fine. But when I adding inside relative nothing happen.
<DragLinearLayout>
<Relative>
<TextView ,height=match ,width=match>
</TextView>
</Relative>
<Relative>
<TextView ,height=match ,width=match>
</TextView>
</Relative>
</DragLinearLayout>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.