Reputation: 20643
I have an app filled with custom buttons for Android. I would like to allow user to rearrange these buttons like image buttons of Home or Application panel.
I researched on this and found out that I can use drag & drop functionality to interact with user's motion. But in my case parent layout can be different. OnMove or OnDrop event, I need to actually move that button in that corresponding layout.
So question is how I can find a layout that contains coordinate x & y and put the button in it.
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
status = START_DRAGGING;
break;
case MotionEvent.ACTION_UP:
status = STOP_DRAGGING;
break;
case MotionEvent.ACTION_MOVE:
if(status == START_DRAGGING){
//parentLayout.setPadding((int)event.getRawX(), 0,0,0);
//**What to do here**
parentLayout.invalidate();
}
break;
}
return true;
}
Upvotes: 4
Views: 2568
Reputation: 134664
I would suggest something to loop through the root XML and check the visible coordinates of any contained ViewGroups; something like this, though this is untested:
ViewGroup root = (ViewGroup)findViewById(R.id.id_of_your_root_viewgroup);
//get event coordinates as int x, int y
public ViewGroup findContainingGroup(ViewGroup v, int x, int y) {
for (int i = 0; i < v.getChildCount(); i++) {
View child = v.getChildAt(i);
if(child instanceof ViewGroup) {
Rect outRect = new Rect();
child.getDrawingRect(outRect);
if(outRect.contains(x, y)) return child;
}
}
}
ViewGroup parent = findContainingGroup(root, x, y);
Upvotes: 2
Reputation: 2659
You can loop through all the controls in the parent container and compare each child's bounds with the current X, Y. You can get a views bounds by calling this:
So something like this:
for(View v : parent.children())
{
// only checking ViewGroups (layout) obviously you can change
// this to suit your needs
if(!(v instanceof ViewGroup))
continue;
if(v.getHitRect().contains(x, y))
return v;
}
This is just Psuedo-code and will need to be adapted for whatever you use is (i.e. adding recursion for nested controls).
Hope that helps.
Upvotes: 8
Reputation: 22822
I would suggest using a TableLayout
. As it's made of rows and columns, you can dynamically reorder them by inserting / deleting rows or columns and rebuilding your whole layout on the fly.
But that probably means you'd have to set you layout programmatically, I can see how you can do that from an XML layout.
(The following is pseudo-code)
if (dropping button) {
calculate new layout based on which row/column button was moved, and where it was dropped;
generate new layout (TableLayout --> addRow --> addView);
apply it to buttons view (Buttons.setView(TableLayoutView));
}
Upvotes: 0