在java中拖动多个按钮视图
Posted
技术标签:
【中文标题】在java中拖动多个按钮视图【英文标题】:Dragging multiple button views in java 【发布时间】:2015-11-23 12:20:34 【问题描述】:我有一个应用程序,我需要在其中移动一堆按钮(就像将一堆卡片的一部分从一堆移动到另一堆一样)。我已经在 xml 布局中定义了所有按钮,并为所有人设置了触摸和拖动侦听器。 我可以单独在屏幕上拖放任何按钮。但在某些情况下,我需要做的是拖动堆叠在我同时单击的原始按钮顶部的其他按钮。 有没有办法“欺骗”或模拟按下另一个按钮(以便侦听器注册它)? 谢谢 ***编辑于 2015 年 9 月 8 日 @覆盖 public boolean onTouch(View v, MotionEvent e) // tosty("mclicking: "+mClicking); int startpos = 0; switch (e.getAction() & MotionEvent.ACTION_MASK)
case MotionEvent.ACTION_DOWN:
isWastePile=false;
get_selected_deck(v); // determines which of 7 decks or layouts in the tablau you have
// clicked
FromDeck = selecteddeck;
FromDeckCard = deckcard;
FromDeckButton = deckbutton;
// if (!mClicking)
mClicking = true;
//String piecetag = (String) v.getTag();
// // IDEA!!!/ ///
/*
* I wrote a function that finds all the ImageButtons below where
* the user clicked, and set them all to invisible. I then created a
* new Linear Layout within the Linear Layout that the user clicked (during the ACTION_DOWN event),
* and passed that into the Drag Shadow builder during the ACTION_MOVE event.
*
* Once into the ACTION_DROP portion, I simply referenced global
* variables to figure out if the user dropped in one or multiple
* ImageButtons, and dealt with them accordingly.
*/
//if (!isWastePile)
//draglayout.setClipChildren(false);
lltemp = new LinearLayout(this);
lltemp.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams llparams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llparams.setMargins(0, -52, 0, 0);
lltemp.setLayoutParams(llparams);
draglayout.addView(lltemp);
for (int i = 0; i < deckstack_list[selecteddeck].size(); i++)
if (v == (draglayout.getChildAt(i)))
startpos = i;
for (int o = i; o < deckstack_list[selecteddeck].size(); o++)
// layout5.removeViewAt(o);
draglayout.getChildAt(o).setVisibility(View.GONE); // all
// buttons
// being
dragtempstack.push((Integer) deckstack_list[selecteddeck].get(o)) ; // dragged
// to
// invisible
// then recreate another linear layout within layout5
// and pass to dragshadow builder
// to do
// also set a GLOBAL variable with stack count (number
// of cards dragged)
lltemp.setClipChildren(false);
lltemp.addView(createtempButtons(o, startpos));
// // end if wastepile check statement
//tosty("dragtempstack size: "+dragtempstack.size());
break;
case MotionEvent.ACTION_MOVE:
//tosty("Action MOVE");
Log.i("ACTION Event: ", "ACTION MOVE");
// v = layout5;
v = lltemp;
v.setVisibility(View.INVISIBLE);
v.bringToFront();
v.invalidate();
v.setVisibility(View.VISIBLE);
//DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
DeckDragShadow shadowBuilder = new DeckDragShadow(v);
v.startDrag(null, shadowBuilder, v, 0);
correctDrag = false;
break;
private Button createtempButtons(final int i, final int startpos)
final Button b = new Button(this);
b.setOnTouchListener(this);
b.setOnDragListener(new DeckDragListener());
b.setBackgroundResource(cardimagearray[dragdeckstack.get(i)]);
float width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
45, getResources().getDisplayMetrics());
float height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
61, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
(int) width, (int) height);
float margTop = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-36, getResources().getDisplayMetrics());
if (i > startpos)
params.setMargins(0, -57, 0, 0);
b.setLayoutParams(params);
// b.bringToFront();
// b.invalidate();
b.setVisibility(View.VISIBLE);
return b;
【问题讨论】:
进一步澄清,纸牌是我需要做的一个很好的例子。单击卡片堆中任意位置的卡片,然后将所有卡片拖动到单击的原始按钮的顶部。我可以通过循环更改所有其他卡片的背景、可见性等,但似乎无法拖动所有卡片。 我假设您已经有了要移动视图的东西,那么为什么不移动按钮,而是创建并移动包含按钮的布局呢? 是的,正确我有线性布局的按钮。如果我将线性布局视图传递到拖动阴影生成器中,所有按钮都会移动。但是当我尝试使用我想要移动的按钮重新创建一个临时线性布局时,例如一半的按钮,我遇到了拖动问题。这是我一直在尝试的一些代码 【参考方案1】:我不会尝试为每个按钮复制侦听器,而是将按钮视为组。当您单击组中的按钮时,它会分成两组:上面有按钮的按钮和您留下的按钮。然后将该组拖放到其他组上。
正如 Templerschaf 所建议的,这些组可以是 LinearLayouts:
你点击LinearLayout 它注册了哪个项目 创建一个新的 LinearLayout,在正确位置包含该项目下方的项目 删除点击项下的项并相应调整大小 然后布局可以继续拖拽 然后可以将其放到另一个 LinearLayout 上,这会将项目添加到自己的列表中这很像 ListView 动画。见:
https://www.youtube.com/watch?v=_BZIvjMgH-Q
https://www.youtube.com/watch?v=mwE61B56pVQ
https://github.com/bauerca/drag-sort-listview/blob/master/library/src/com/mobeta/android/dslv/DragSortListView.java
【讨论】:
我有点理解你的意思,我在创建新的 LinearLayout 后卡住了(dragshadow 不会随着新布局更新),因为我已经点击了按钮,它开始了你建议的过程1.单击布局,2.我检测/注册哪个按钮,3.我创建一个新的临时线性布局,顶部附加按钮并将其传递给dragshadow,但是如何让图像更新为新的线性当我还在触摸按钮时布局?在拖动过程中,它仍然只拖动我点击的原始按钮。 一旦我完成拖动,新的线性布局就会被绘制到屏幕上。我也需要在拖动前的第一次按下或长按时发生这一切。希望这是有道理的 您可能希望在 Button 和包含该按钮的行布局上将 clickable 设置为 false,以便 LinearLayout 处理拖动。您需要分别响应初始单击和拖动,因此您可能需要 onTouchEvent。我认为这是在我链接到的第一个视频中完成的。我不相信您需要像该视频中那样创建 BitmapDrawable:使用 LinearLayout 应该是可能的。 感谢大家的帮助,我终于找到工作了,也许不太理想,性能会告诉我是否会保留这种方法。但最大的不同在于 onTouch 方法,我将创建另一个布局和使用新布局创建拖动阴影这两个动作分开。我使用 ACTION_DOWN 事件来执行所有视图的创建和删除等操作。然后在 ACTION_MOVE 部分中,我将新创建的布局传递给 dragshadow 构建器。 然后使用一些额外的命令,比如bringToFront(新布局出现在预先存在的图像后面)和invalidate() 来重绘。我现在可以将多个图像从一个布局拖放到另一个布局。以上是关于在java中拖动多个按钮视图的主要内容,如果未能解决你的问题,请参考以下文章