Можно ли поставить элементы ViewGroups перед родственными ViewGroups?

Я не уверен, что мой вопрос понятен. В моем макете есть Image и ViewGroup. ViewGroup можно сравнить с GridView, где у меня есть элементы, которые я могу перетаскивать. Теперь мне интересно перетаскивать элементы моего ViewGroup по изображению, но каждый раз, когда я пытаюсь, элементы имеют более низкий z-индекс, потому что они исчезают за изображением.

Я уже пробовал комбинации с bringToFront на ViewGroup и его элементах, но ничего не получалось. Теперь мой вопрос в том, возможно ли вообще поставить viewgroups элементы перед viewgroups родным братом. У кого-нибудь есть опыт в этом?

Мой xml выглядит так, где GridView - это мой Viewgroup... ресурс изображения и видимость изображения задаются в коде:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_gridview_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="@string/tag_fragment_GridView"
android:background="#FFF"
android:orientation="vertical" >

<ImageView
    android:id="@+id/img"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:visibility="gone" />


<de.test.GridView
    android:id="@+id/grid_view1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/img"
    android:background="#FFF"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="none"
    android:tag="grid_view_tag" >
</de.test.GridView>

EDIT: I use a BaseAdapter to display the layout, because I have a dynamically amount of pages, that can be flipped using this library https://github.com/openaphid/android-flip.

Макет, который я создаю, выглядит следующим образом:

public View loadView(final View view, final int position) {

    final GridView dgv = (GridView) view
            .findViewById(R.id.grid_view1);


    dgv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(android.widget.AdapterView<?> arg0, View v,
                int position, long arg3) {

            // Simple click listener for the items...



        }
    });

    dgv.getViewTreeObserver().addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {
                    if (Build.VERSION.SDK_INT < 16) {
                        dgv.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                    } else {
                        dgv.getViewTreeObserver()
                                .removeOnGlobalLayoutListener(this);
                    }

                    int displayHeight = view.getHeight();
                    int displayWidth = view.getWidth();


                        dgv.initChilds(displayWidth, displayHeight,
                                2,
                                2);
                    } else {
                        mImage = (ImageView) view
                                .findViewById(R.id.img);
                        mImage.getLayoutParams().height = displayHeight / 2;

                        mImage.setImageResource(R.drawable.bild);


                        dgv.initChilds(displayWidth,
                                displayHeight / 2, 2,
                                2);
                    }

                    updateGridView();
                }

            });

    mList.add(view);

    return view;
}

initChilds()-Methods определяет размер каждого элемента группы просмотра. Я хотел бы установить элемент группы просмотра на передний план, когда он выбирается длинным щелчком. Longclicklistener выглядит так:

@Override
public boolean onLongClick(View view) {

    draggedItem = getDraggedView(); draggedItem.bringToFront();
    callback.bringGridToFront();            

    return true;
}

Я пытаюсь вывести элемент на передний план вот так, но это не работает... переменная обратного вызова является экземпляром класса базового адаптера, который вызывает метод BringGridToFront(), который в настоящее время выполняет следующий код:

public void bringGridToFront() {
    View view = mList.get(mCurrentPage);
    RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.relative_gridview_layout);
    GridView dgv = (GridView) view.findViewById(R.id.grid_view1);       
    rl.bringChildToFront(dgv);
}

person androider    schedule 09.07.2013    source источник
comment
Я подумал о чем-то вроде этого: gridView.bringToFront(); элемент.bringToFront(); Где элемент - это перетаскиваемый элемент сетки... но он не работает   -  person androider    schedule 09.07.2013
comment
Я думаю, что есть функция BringChildToFront. В вашем случае вам придется называть это так (relative_gridview_layout).bringchildtofront(grid_view1).   -  person ChD Computers    schedule 09.07.2013
comment
Эй, Христос, спасибо за ваш ответ;) Я попробовал ваше предложение, но, к сожалению, это не сработало ... если я попытаюсь перетащить дочерний элемент группы просмотра по изображению, он все равно останется позади   -  person androider    schedule 09.07.2013
comment
разместите какой-нибудь код, возможно, вам не хватает чего-то, что кто-то здесь может увидеть и дать ответ...   -  person ChD Computers    schedule 09.07.2013
comment
опубликуйте код, готово: D   -  person androider    schedule 09.07.2013
comment
По крайней мере, я написал класс представления, который расширяет относительный макет и использует его в xml. Затем я пытаюсь вывести gridview на передний план с помощью метода getChildDrawingOrder(...) из относительного макета... но все равно безуспешно.   -  person androider    schedule 10.07.2013


Ответы (3)


Android управляет z-индексом на основе позиции представления в таблице дерева макетов. Представление с самым большим индексом рисуется поверх других. В вашем макете ваша пользовательская сетка находится поверх других, потому что это последний вид в макете и, следовательно, он получает самый большой индекс.

В вашем коде я вижу, что вы звоните

draggedItem = getDraggedView();

в событии onLongClick(View view). getDraggedView() может возвращать представление, которое является представлением, которое вы перетаскиваете, и оно не отображается сверху (это всего лишь предположение, поскольку вы не публикуете код getDraggedView()). Если это так, вам нужно знать родителя перетаскиваемого представления, если, например, родителем является главное окно, тогда весь ваш макет будет поверх него. Поэтому я думаю, что лучше всего добавить перетаскиваемый вид в макет, и, поскольку это будет последний вид, он будет отображаться сверху.

Кроме того, я заметил, что вы звоните

mImage.getLayoutParams().height = displayHeight / 2;

в вашем представлении изображения, чтобы изменить его высоту. Я не думаю, что это правильный способ сделать это, потому что если взглянуть на исходный код View здесь в строке 10130, в которой находится код setLayoutParams, вы увидите, что помимо набора параметров макета происходят некоторые другие вещи. Однако я не знаю, связано ли это с вашей проблемой или нет.

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

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

person ChD Computers    schedule 10.07.2013

Спасибо за помощь. Наконец, метод BringToFront() не работает для меня. Теперь я могу решить свою проблему, используя метод getChildDrawingOrder(), переопределенный из ViewGroups.

С помощью этого метода вы можете изменить порядок отрисовки дочерних элементов и, наконец, нарисовать элемент, который хотите разместить над всеми остальными. Пример:

@Override
public int getChildDrawingOrder(int childCount, int i) {
    if(mDragged != -1) {

        if(i == mDragged) {
            return childCount-1;
        }
        else if(i == (childCount - 1)) {
            return mDragged;
        }       
        else {
            return i;
        }
    }

    return i;
}

mDragged — это переменная, которая должна быть впереди. Поэтому я изменил позицию рисования этой переменной на последнюю... надеюсь, что это поможет всем, у кого была такая же проблема: D

person androider    schedule 15.07.2013

Я попробовал принятый ответ, но продолжал получать сбои всякий раз, когда были дочерние представления, которые не отображались. Проблема заключалась в том, что параметры childCount и i относятся к видимым дочерним элементам, а не ко всему списку дочерних элементов. Это решение основано на этом ответе и включает эту корректировку индексов.

@Override
public int getChildDrawingOrder(int childCount, int i) {
   int firstVisiblePosition = getFirstVisiblePosition();
   if (mDragged < firstVisiblePosition || mDragged > getLastVisiblePosition())
      return super.getChildDrawingOrder(childCount, i);
   int adjustedDragged = mDragged - firstVisiblePosition;
   if (i == adjustedDragged)
       return childCount - 1;
   if (i == (childCount - 1))
      return adjustedDragged;
   return i;
}
person user6487473    schedule 20.06.2016
comment
Это новый вопрос вместо ответа. используйте ссылку Задать вопрос, чтобы задать новый вопрос - person ρяσѕρєя K; 20.06.2016