最初に少しの背景:
スクロールビュー内にレイアウトがあります。最初に、ユーザーが画面をスクロールすると、スクロールビューがスクロールします。ただし、一定量のスクロールの後、スクロールビューのスクロールを無効にして、「スクロールフォーカス」を子レイアウト内の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を明確に呼び出しています。
溶液:
((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout);
//scrollView.removeView(scrollChildLayout);
子要素を使用して、親への参照を取得します。 removeViewメソッドにアクセスして使用できるように、親をViewGroupにキャストします。
ソリューションを提供してくれた@Dongshengcnに感謝
最初に親ビューからscrollChildLayoutを削除してみてください?
scrollview.removeView(scrollChildLayout)
または、親ビューからすべての子を削除して、再度追加します。
scrollview.removeAllViews()
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) {
}
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を教えてくれてありがとう)removeView
はViewManager
インターフェイスの一部です。そして、完全に適切なインターフェースが利用可能な場合、具体的なクラスにキャストすべきではありません。
必要なのは、addView()を実行するRunnableをpost()することだけです。
ParentView.removeView(childView)を呼び出していましたが、childViewはまだ表示されていました。最終的に、メソッドが何らかの形で2回トリガーされることに気付き、childViewをparentViewに2回追加しました。
したがって、parentView.getChildCount()を使用して、ビューを追加する前と後の親の子の数を判断します。子が何度も追加されると、一番上の子が削除され、childViewのコピーが残ります。removeViewが動作している場合でも動作しているように見えます。
また、View.GONEを使用してビューを削除しないでください。本当に削除されている場合は、非表示にする必要はありません。それ以外の場合はまだ存在しているので、自分から非表示にしているだけです:(
私の場合、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);
私が間違っていたのでこのエラーが出ました
これが私の解決策です。
2つの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());