Сначала вызовите removeView () у родителя ребенка - PullRequest
131 голосов
/ 30 июня 2011

Сначала немного фона:

У меня есть макет внутри прокрутки.Сначала, когда пользователь прокручивает на экране, прокрутка прокручивается.Однако после определенного количества прокрутки я должен был отключить прокрутку в представлении прокрутки и переместить «фокус прокрутки» на веб-просмотр внутри дочернего макета.Таким образом, палочки прокрутки и все события прокрутки переходят в веб-представление внутри него.

Таким образом, для решения, когда порог прокрутки достигнут, я удаляю дочерний макет из прокрутки и помещаю его в представление прокрутки.parent. (и сделать представление прокрутки невидимым).

// Remove the child view from the scroll view
scrollView.removeView(scrollChildLayout);

// Get scroll view out of the way
scrollView.setVisibility(View.GONE);

// Put the child view into scrollview's parent view
parentLayout.addView(scrollChildLayout);

Общая идея: (-> означает содержит)

До: parentlayout -> scrollview -> scrollChildLayout

После: parentLayout -> scrollChildLayout

Приведенный выше код дает мне следующее исключение:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
           at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
           at android.view.ViewGroup.addView(ViewGroup.java:1871)
           at android.view.ViewGroup.addView(ViewGroup.java:1828)
           at android.view.ViewGroup.addView(ViewGroup.java:1808)

Знаете ли вы, что происходит?Я явно вызываю removeView для родителя.

Ответы [ 10 ]

282 голосов
/ 30 июня 2011

Решение:

((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout);
//scrollView.removeView(scrollChildLayout);

Используйте дочерний элемент, чтобы получить ссылку на родителя.Приведите родительский элемент к ViewGroup, чтобы получить доступ к методу removeView и использовать его.

Спасибо @Dongshengcn за решение

22 голосов
/ 30 июня 2011

Попробуйте сначала удалить scrollChildLayout из родительского представления?

scrollview.removeView(scrollChildLayout)

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

scrollview.removeAllViews()
19 голосов
/ 29 мая 2014

В onCreate с активностью или в onCreateView с фрагментом.

 if (view != null) {
    ViewGroup parent = (ViewGroup) view.getParent();
    if (parent != null) {
        parent.removeView(view);
    }
}
try {
    view = inflater.inflate(R.layout.fragment_main, container, false);
} catch (InflateException e) {

}
16 голосов
/ 02 октября 2013

Хорошо, назовите меня параноиком, но я предлагаю:

  final android.view.ViewParent parent = view.getParent ();

  if (parent instanceof android.view.ViewManager)
  {
     final android.view.ViewManager viewManager = (android.view.ViewManager) parent;

     viewManager.removeView (view);
  } // if

кастинг без instanceof просто кажется неправильным. И (спасибо IntelliJ IDEA за сообщение) removeView является частью интерфейса ViewManager. И не следует приводить к конкретному классу, когда доступен идеально подходящий интерфейс.

3 голосов
/ 30 июня 2011

Все, что вам нужно сделать, это опубликовать () Runnable, который выполняет addView ().

1 голос
/ 24 декабря 2017

В моем случае у меня есть BaseFragment и все остальные фрагменты наследуются от него.

Так что мое решение было добавить эту строку в OnDestroyView() метод

@Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    if (mRootView == null)
    {
        mRootView = (inflater == null ? getActivity().getLayoutInflater() : inflater).inflate(mContentViewResourceId, container, false);
    }
....////
}

@Override
public void onDestroyView()
{
    if (mRootView != null)
    {
        ViewGroup parentViewGroup = (ViewGroup) mRootView.getParent();

        if (parentViewGroup != null)
        {
            parentViewGroup.removeAllViews();
        }
    }

    super.onDestroyView();
}
1 голос
/ 04 февраля 2014

Я звонил parentView.removeView (childView), а childView все еще показывал.В конце концов я понял, что метод каким-то образом запускается дважды, и дважды добавил childView к parentView.

Итак, используйте parentView.getChildCount (), чтобы определить, сколько дочерних элементов имеет родительский объект до добавления представления и после него.Если дочерний объект добавляется слишком много раз, удаляется самый верхний дочерний элемент, и копия childView остается, что похоже на то, что removeView работает, даже если это так.

Кроме того, вы не должны использовать View.GONE дляудалить вид.Если он действительно удален, вам не нужно его скрывать, иначе он все еще там, и вы просто скрываете это от себя: (

0 голосов
/ 02 января 2018

Вот мое решение.

Допустим, у вас есть два TextViews и поместите их в LinearLayout (названный ll). Вы положите это LinerLayout на другое LinerLayout.

< lm Linear Layout> 
       < ll Linear Layout> 
             <name Text view>
             </name Text view>
             <surname Text view>
             </surname Text view>
       </ll Linear Layout> 
</lm Linear Layout> 

Когда вы хотите создать эту структуру, вам нужно предоставить parent как наследство.

Если вы хотите использовать его в onCreate методе this будет достаточно.

В противном случае вот решение:

LinerLayout lm = new LinearLayout(this); // You can use getApplicationContext() also
LinerLayout ll = new LinearLayout(lm.getContext());
TextView name = new TextView(ll.getContext());
TextView surname = new TextView(ll.getContext());
0 голосов
/ 12 декабря 2017

Что я делал не так, поэтому у меня возникла ошибка: я не создал экземпляр динамического макета и не добавил в него дочерние элементы, поэтому получил эту ошибку

0 голосов
/ 21 августа 2013

Вы также можете сделать это, проверив, есть ли у метода indexOfView View если метод indexOfView возвращает -1, тогда мы можем использовать.

ViewGroup's detachViewFromParent (v); с последующим RemoveDetachedView от ViewGroup (v, true / false);

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