Как отправить вид назад? Как программно управлять z-порядком? - PullRequest
53 голосов
/ 20 июля 2011

У меня проблема с отправкой представления назад.В Android у нас есть метод, такой как bringToFront(), чтобы поместить представление поверх другого представления.Таким образом, я хочу поставить вид ниже предыдущего изображения.

Существует ли какой-либо метод, например sendToBack() или bringToBack() в Android.Если да, может ли кто-нибудь помочь мне в этом.

Примечание: я не хочу управлять z-порядком по порядку размещения элементов в макете. Я хочу управлять z-порядком программно.

Я не хочу скрывать виды спереди, я просто хочу, чтобы они были позади движущегося вида.

Ответы [ 12 ]

62 голосов
/ 09 ноября 2013

Я понимаю, что это подразумевалось в других ответах, но никто не опубликовал код.Я храню следующее в служебном классе, где у меня есть «вспомогательные» функции для работы с представлениями:

public static void sendViewToBack(final View child) {
    final ViewGroup parent = (ViewGroup)child.getParent();
    if (null != parent) {
        parent.removeView(child);
        parent.addView(child, 0);
    }
}
38 голосов
/ 16 февраля 2012

Нет sendToBack() метода. Но если вы позвоните bringToFront() в нижнем позиционном представлении, вы получите почти тот же эффект.

32 голосов
/ 20 июля 2011

Афайк, для этого нет встроенного решения.Я предполагаю, что вы пытаетесь изменить z-порядок в FrameLayout или что-то подобное.

Однако я думаю, что вы можете изменить порядок содержащихся дочерних элементов в макете.Методы RemoveChild ... () и addView () могут принимать значения положения, так что вы, скорее всего, можете поменять местами дочерние элементы, что приведет к изменению z-порядка.Тем не менее, это кажется немного хакерским решением.

Или рассмотрите возможность изменения свойства видимости дочерних представлений, вы можете получить похожее поведение, и я думаю, это будет намного чище.

Редактировать:

С новой версией Android, L Developer Preview, кажется, что, наконец, у нас есть возможность легко изменить Z-порядок просмотров.Свойства 'Elevation' и 'TranslationZ' для спасения: https://developer.android.com/preview/material/views-shadows.html

19 голосов
/ 21 февраля 2012

Вызовите bringToFront() на виде, который вы хотите получить спереди, а затем вызовите метод invalidate() на всем виде, включая вид, который вы хотите спереди. Повторите то же самое для всех слушателей.

Таким образом, когда будет вызван слушатель другого представления, предыдущее представление станет недействительным и будет в фоновом режиме.

8 голосов
/ 29 июня 2013

Вот метод, который я использую, чтобы отправить View назад (так, противоположно методу takeToFront, вроде sendToBack):

    private void moveToBack(View myCurrentView) 
    {
        ViewGroup myViewGroup = ((ViewGroup) myCurrentView.getParent());
        int index = myViewGroup.indexOfChild(myCurrentView);
        for(int i = 0; i<index; i++)
        {
            myViewGroup.bringChildToFront(myViewGroup.getChildAt(i));
        }
    }

Надеюсь, это поможет!

2 голосов
/ 21 сентября 2017

все работает нормально, как в режиме takeToBack ()

public void moveToBack(ViewGroup viewGroup, View v) {
    int s = 1;
    for (int i = 1; i < viewGroup.getChildCount(); i++) {
        if (viewGroup.getChildAt(1) == v) {
            s = 2;
        } else {
            viewGroup.getChildAt(s).bringToFront();
        }
    }
}
2 голосов
/ 23 октября 2015

Обратите внимание, что вы можете использовать view.setZ(float), начиная с уровня API 21. Здесь вы можете найти больше информации.

1 голос
/ 18 ноября 2018

В вашем XML-файле вы должны записать в следующем порядке:

<FrameLayout
android:id="@+id/frameLayoutXML"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
<ImageView
 android:id="@+id/imageViewXML"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/floatB_XML"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>

В этом случае imageView вернется к FloatingActionButton.

Если вы хотите изменитьчто-то, и тогда вы сделаете это программно:

public class SomeActivity extends AppCompatActivity {

    //declare variables
    ImageView imageView;
    FrameLayout frameLayout;
    FloatingActionButton floatingActionButtonNew;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Here is to call what already exists at XML file
        frameLayout=findViewById(R.id.frameLayoutXML);   
        imageView = findViewById(R.id.imageViewXML);
        //Here is to declare a new Element to add to the view, but is not at XML File
        floatingActionButtonNew=New FloatingActionButton(this);
        frameLayout.removeAllViews();  //here you remove all views.
        frameLayout.addView(imageView);//And you add again the imageView first
        floatingActionButtonNew.setLayoutParams(new 
         RelativeLayout.LayoutParams(
          RelativeLayout.LayoutParams.WRAP_CONTENT,
          RelativeLayout.LayoutParams.WRAP_CONTENT
        )); //Then you can give some format to your floatingButtonNew

        //And finally  add to the frameLayout the new View in this case the floatingButtonNew
        frameLayout.addView(floatingActionButtonNew);
    }
}

В этом порядке объявлений представлений у вас снова будет изображение назад от плавающей кнопки.Таким образом, представление, которое объявлено первым, будет возвращено из представления, которое объявлено вторым, и ключом для достижения порядка является removeAllViews из FrameLayout или LinearLayout и добавление этих представлений снова при программном добавлении..

1 голос
/ 13 декабря 2011

Вы также можете попытаться использовать функциональные возможности метода ViewGroup.addViewInLayout(), которые берут индекс, определяя, должно ли представление быть в конце или в начале списка

0 голосов
/ 19 марта 2018

Если вы используете библиотеку appCompat, есть другой способ изменить Z-порядок для устройств ниже 21 уровня API:

ViewCompat.setTranslationZ(view, zValue);
...