Сначала вызовите removeView () для родителя ребенка



сначала немного предыстории:



у меня есть макет внутри scrollview. Сначала, когда пользователь прокручивает на экране, прокручивается scrollview. Однако после определенного количества прокрутки я должен был отключить прокрутку в режиме прокрутки, переместив "фокус прокрутки" на веб-представление внутри дочернего макета. Таким образом, ScrollView палочки и все события прокрутки перейти к webview внутри него.



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



// 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 на родителя.

443   10  

10 ответов:

устранение:

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

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

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

Попробуйте удалить scrollChildLayout от своих родителей смотреть в первую очередь?

scrollview.removeView(scrollChildLayout)

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

scrollview.removeAllViews()

в 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) {

}

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

  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 интерфейс. И не следует бросать в конкретный класс, когда доступен идеально подходящий интерфейс.

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

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

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

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

в моем случае, у меня есть 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();
}

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

ViewGroup(в); с последующим RemoveDetachedView ViewGroup(в, верно/неверно);

то, что я делал неправильно, поэтому я получил эту ошибку, я не создавал динамический макет и не добавлял к нему детей, поэтому получил эту ошибку

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

допустим, у вас есть два 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> 

когда вы хотите создать эту структуру нужно отдать родителей в качестве наследства.

если вы хотите использовать его в 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());

Comments

    Ничего не найдено.