简体   繁体   中英

Find layout with x,y coordinate

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;
}

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:

View.getHitRect()

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 (ie adding recursion for nested controls).

Hope that helps.

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);

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));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM