web-dev-qa-db-ja.com

最初に子の親でremoveView()を呼び出します

最初に少しの背景:

スクロールビュー内にレイアウトがあります。最初に、ユーザーが画面をスクロールすると、スクロールビューがスクロールします。ただし、一定量のスクロールの後、スクロールビューのスクロールを無効にして、「スクロールフォーカス」を子レイアウト内のWebビューに移動しました。このように、スクロールビューは固定され、すべてのスクロールイベントはその内部のWebビューに移動します。

したがって、解決策として、スクロールのしきい値に達すると、スクロールビューから子レイアウトを削除し、スクロールビューの親に配置します(そして、スクロールビューを非表示にします)。

// 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を明確に呼び出しています。

131
kasgoku

溶液:

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

子要素を使用して、親への参照を取得します。 removeViewメソッドにアクセスして使用できるように、親をViewGroupにキャストします。

ソリューションを提供してくれた@Dongshengcnに感謝

281
kasgoku

最初に親ビューからscrollChildLayoutを削除してみてください?

scrollview.removeView(scrollChildLayout)

または、親ビューからすべての子を削除して、再度追加します。

scrollview.removeAllViews()
22
dongshengcn

OnCreate with activityまたはonCreateView in fragment。

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

}
19
Cabezas

OK

  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を教えてくれてありがとう)removeViewViewManagerインターフェイスの一部です。そして、完全に適切なインターフェースが利用可能な場合、具体的なクラスにキャストすべきではありません。

16
Martin

必要なのは、addView()を実行するRunnableをpost()することだけです。

3
Romain Guy

ParentView.removeView(childView)を呼び出していましたが、childViewはまだ表示されていました。最終的に、メソッドが何らかの形で2回トリガーされることに気付き、childViewをparentViewに2回追加しました。

したがって、parentView.getChildCount()を使用して、ビューを追加する前と後の親の子の数を判断します。子が何度も追加されると、一番上の子が削除され、childViewのコピーが残ります。removeViewが動作している場合でも動作しているように見えます。

また、View.GONEを使用してビューを削除しないでください。本当に削除されている場合は、非表示にする必要はありません。それ以外の場合はまだ存在しているので、自分から非表示にしているだけです:(

1
Chris Sprague

私の場合、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メソッドが-1を返す場合、ViewのindexOfViewメソッドをチェックすることでもできます。

ViewGroupのdetachViewFromParent(v);続いて、ViewGroupのremoveDetachedView(v、true/false);

0
Arun Gupta

私が間違っていたのでこのエラーが出ました

0
blackHawk

これが私の解決策です。

2つのTextViewsがあり、それらをLinearLayoutllという名前)に配置するとします。この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());
0
ishak O.