How to bring a view to front without calling bringToFront()?

你说的曾经没有我的故事 提交于 2019-11-28 07:51:27

问题


There is apparently a bug in Android which breaks View.bringToFront.

If I have Views arranged in a GridView and want to bring a View to front by calling bringToFront(), it may get moved to the bottom right position in the GridView.

Something shady is going on there, so I can't use bringToFront(). When I don't call it, everything works fine. But the Views overlap - if I use scale animation to scale up a View, it's partially obscured by the Views to the bottom and to the right.

I've checked out bringToFront's source and it calls parent.bringChildToFront(...)

it's this method

public void bringChildToFront(View child) {
     int index = indexOfChild(child);
      if (index >= 0) {
          removeFromArray(index);
          addInArray(child, mChildrenCount);
          child.mParent = this;
      }
  }

it apparently removes the View from itself! Without mercy! Is a ViewGroup so dumb that it can't manage Z-indexes in any other way that shuffling controls around? Obviously when GridView removes its child and then adds it back again, it gets placed at the end of the Grid!

Is there anything I can do to show a View on top of others without resorting to some hacking? One thing that comes to my mind is to create another View above the GridView, which will appear to be above the one I'm trying to bringToFront(), but I don't like this solution.


回答1:


apparently I missed the android:clipChildren="false" property in GridView. It solves my problem.




回答2:


Have you tried making the View focusable and just calling requestFocus()?




回答3:


Calling bringToFront() changes the ordering in the GridView. Try creating an ImageView with an image of the view you want to animate and animate that instead.

Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
final ImageView imageView = new ImageView(getActivity());
imageView.setImageBitmap(bitmap);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(view.getWidth() , view.getHeight());
imageView.setLayoutParams(params);
rootview.addView(imageView);

Add an animation listener to your animation and remove the ImageView at the end of the animation.




回答4:


From API 21 you can call:

view.setZ(float)



回答5:


If you target API above 21, you can simply add the attribute android:translationZ="xxx dp" to your XML.

Please note that if you add elevation in views like cardview, you go into the Z axis. And if you want a view come to foreground using this way, you just have to make it higher than the elevation you set.

Example : 6 dp elevation in cardview will require a 7dp in the attribute translationZ of the view you want foreground.



来源:https://stackoverflow.com/questions/4392179/how-to-bring-a-view-to-front-without-calling-bringtofront

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!