我正在尝试让 ViewDragHelper
与垂直 LinearLayout
一起使用, - 容器 - 具有
A ---- List View
B ---- horizontal linear layout
C ---- Support Map Fragment
作为 child 的观点。
A 具有 layout_height="0dp"
。向下拉 B,应按比例增加 A 的高度,从而显示 ListView
上的内容,从而在此过程中自动重新定位 B 并调整 C 的大小。
以下是容器LinearLayout
的代码。
public class MyLinearLayout extends LinearLayout {
private LinearLayout headerLayout;
private ListView filtersListView;
private ViewDragHelper viewDragHelper;
private int MARGIN;
public MyLinearLayout (Context context) {
super(context);
init();
}
public MyLinearLayout (Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyLinearLayout (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
viewDragHelper = ViewDragHelper.create(this, 1, new DragHelperCallback());
float GESTURE_THRESHOLD_DP = 10.0f;
float scale = getResources().getDisplayMetrics().density;
MARGIN = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);
}
@Override
protected void onFinishInflate() {
Log.i("Places", "onFinishInflate");
super.onFinishInflate();
headerLayout = (LinearLayout) findViewById(R.id.header);
filtersListView = (ListView) findViewById(R.id.filters_list);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i("Places", "onInterceptTouchEvent");
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i("Places", "onTouchEvent");
viewDragHelper.processTouchEvent(event);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) event.getRawY());
layoutParams.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);
filtersListView.setLayoutParams(layoutParams);
return true;
}
private class DragHelperCallback extends ViewDragHelper.Callback {
@Override
public boolean tryCaptureView(View child, int pointerId) {
Log.i("Places", "tryCaptureView " + (child == headerLayout));
return child == headerLayout;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
Log.i("Places", "onViewPositionChanged " + changedView.getClass().getName());
super.onViewPositionChanged(changedView, left, top, dx, dy);
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
Log.i("Places", "onViewReleased " + releasedChild.getClass().getName());
super.onViewReleased(releasedChild, xvel, yvel);
}
}
}
我查看了以下内容。
最佳答案
你的ViewDragHelper
有点不对劲。具体来说,您缺少 clampViewPositionVertical()
覆盖,这是启用 View 拖动所必需的。现在,您的 ViewDragHelper
实际上没有执行任何操作。您可能会收到一些 Action ,因为您直接为每个 onTouchEvent()
操作 LayoutParams
,这也会导致一些问题。
您可能希望回调代码看起来更像这样:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
viewDragHelper.processTouchEvent(event);
return true;
}
private class DragHelperCallback extends ViewDragHelper.Callback {
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
//Never go below fully visible
final int bottomBound = getHeight() - child.getHeight();
//Never go above the top
final int topBound = 0;
return Math.max(Math.min(top, bottomBound), topBound);
}
@Override
public boolean tryCaptureView(View child, int pointerId) {
//Capture touches to the header view
return child == headerLayout;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
if (dy == 0) return;
//React to the position change of the header by modifying layout
LinearLayout.LayoutParams layoutParams = (LayoutParams) filtersListView.getLayoutParams();
layoutParams.height += dy;
filtersListView.setLayoutParams(layoutParams);
}
}
这将设置“标题 View ”的拖动范围,以便在容器 View 的顶部和底部之间自由移动(夹紧它,这样它就不会离开屏幕)。就其本身而言,这只会移动标题 View 。将 LayoutParams
代码移至 onViewPositionChanged()
中,让您的顶部/底部 View 对精确的拖动距离使用react。
两个警告:
- 不要向
LayoutParams
添加边距。您使用它们不断修改比例的方式将导致拖动跳跃。如果您需要插入ListView
内容,请使用 padding 或其他嵌套容器。 - 像这样连续更改整个 View 的布局可能会非常昂贵(布局传递并不便宜,每次修改
LayoutParams
时都会触发一次)。这可能适用于非常简单的布局,但如果您的 View 变得更加复杂,您可能会发现旧硬件上的性能受到影响。
关于java - 查看 Drag Helper 助手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34986752/