我正在实施一个时间选择器,如下所示:
该黄色块是MyCustomView
。移动MyCustomView
时,我应该计算新日期并设置tvDate
。
部分布局文件:
<LinearLayout
android:orientation="vertical">
<TextView android:id="@+id/tv_date">
<RelativeLayout
android:id="@+id/rl">
<MyCustomView
android:layout_centerInParent="true"/>
<OtherViews/>
</RelativeLayout>
</LinearLayout>
代码:
class MyCustomView extends View{
// move listener
public interface IMoveCallback{
void update(int index);
}
private IMoveCallback listener = null;
// set listener
public void setMoveCallback(IMoveCallback callback){
this.listener = callback;
}
@Override
protected void onDraw(Canvas c){
super.onDraw(c);
// draw yellow block and four arrows here.
}
@Override
public boolean onTouch(View v, MotionEvent event) {
processDrag(v, event);
invalidate();
return false;
}
private void processDrag(View v, MotionEvent event){
// calculate new position(left, top, right, bottom)
v.layout(newLeft, newTop, newRight, newBottom);
if(listener != null){
// calculate index by new position
listener.update(index);
}
}
}
class MainActivity extends Activity implements MyCustomView.IMoveCallback{
MyCustomView view; // view.setMoveCallback(MainActivity.this)
@Override
public void update(int index){
tvDate.setText(String.valueOf(System.currentTimeMillis()))//update tvDate
}
}
如果删除了tvDate.setText()
,MyCustomView
会跟在手指后面,如下所示:
如果我更新tvDate
,MyCustomView
会移回rl
的中心:
我认为这不是一个活动 - 生命周期问题。有人提到((MarginLayoutParams)rl.getLayoutParams()).topMargin
,但没有解释原因
有人可以帮帮我吗?
答案 0 :(得分:1)
您的解决方案是在invalidate
CustomView
之后 TextView.setText()
setText()
,然后再布置或传入左边的值, ...
private void processDrag(View v, MotionEvent event){
if(listener != null){
// calculate index by new position
listener.update(index);
}
// calculate new position(left, top, right, bottom)
v.layout(newLeft, newTop, newRight, newBottom);
}
//i think you should take out invalidate() in your onTouch()
为什么呢? TextView.setText()
触发invalidate
&amp;同时requestLayout()
强制快速布局,但Invalidate()
只是告诉其父级它是脏的,所以它需要做一个自上而下的布局传递。
(我很困惑所以我不会继续支持它,因此我跳)。您的TextView
位于父级布局中,其子孙是您的自定义视图,而invalidate()
会重新放置所有这些视图,因此会将您的自定义视图发送回其位置,但是如果您将其排除在外,则会调用它在“自定义”视图中显式invalidate()
,它告诉父项它的脏和相同的过程发生,但这次仅使用RelativeLayout
用户:Zaid Qureshi已经知道了这一点。
另外我不知道你是否知道给你的customView提供的layoutParams是来自你不能控制多少但是操作系统的父系,并且注入的Params是用于布局和给填充等等的东西给你的查看,因为你没有将它们排出,只是通过位置。
希望我对你有意义。它有帮助
答案 1 :(得分:0)
您需要保存视图的位置,并在活动恢复(从家中回来)或开始(在按下后返回)时将其渲染到同一位置。 This Picture显示了您可以覆盖以实现该方法的方法,例如失去焦点时的onPause等。
修改强>
从它的外观来看,它正在重置回原始状态。发布更多关于如何设置位置的信息等。如果这是一个你正在移动的视图。然后实现on drag listener而不是更新。让我知道这是如何工作的。