Android custom view returns to initial position when updated

I am performing a timing that looks like this:

incomplete timing

This yellow block is MyCustomView . When moving MyCustomView I have to calculate a new date and set tvDate .

partial layout file:

 <LinearLayout android:orientation="vertical"> <TextView android:id="@+id/tv_date"> <RelativeLayout android:id="@+id/rl"> <MyCustomView android:layout_centerInParent="true"/> <OtherViews/> </RelativeLayout> </LinearLayout> 

code:

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

If tvDate.setText() is deleted, MyCustomView follows the finger, for example:

enter image description here

If I update tvDate , MyCustomView returns to the rl center:

enter image description here

I do not think this is a life cycle problem. Someone mentioned ((MarginLayoutParams)rl.getLayoutParams()).topMargin but didn't explain why. Can anybody help me?

+5
source share
2 answers

You need to save the location of your view and display it in the same place when the action resumes (returns from home) or begins (returns after clicking). This figure shows the methods that you can override to achieve goals such as onPause when you lose focus, etc.

EDIT

In appearance, it returns to its original state. Post more about how you set your location, etc. If this is the view you are moving. Then use the drag and drop listener instead of this update. And let me know how it works.

0
source

Your solution is to invalidate your CustomView after TextView.setText() setText() before layout or passing values โ€‹โ€‹for your left, hard, ...

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

Why? TextView.setText() triggers invalidate and requestLayout() at the same time for forced layout, but Invalidate() just tells the parent object that it is dirty, so it needs to execute the top layout.

(im confused, so I will not continue to support this, so I am jumping). Your TextView is inside the parent layout, in which the grandiose child is your usual view, and Invalidate() re-lays all of them, so it sends your custom view back to its position, however, if you exclude it, and call explicit Invalidate() in your user view it tells the parent that its dirty same process is happening, but this time only with RelativeLayout

User: Zeid Qureshi has already informed you about this.

Also, I donโ€™t know if you know that the layoutParams provided to your customView belongs to the parent staff that you do not control, but os, and the introduced Params are what are used for the layout, and give additions, etc. for your view, and since you do not post them, you simply skip the position.

I hope I have a point for you and it helps

+1
source

Source: https://habr.com/ru/post/1244708/


All Articles