Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当指定的contentId布局宽高有权重或者是约束布局的子View的时候宽高显示不正常。 #1

Open
oOJohn6Oo opened this issue Sep 26, 2019 · 2 comments

Comments

@oOJohn6Oo
Copy link

项目中类似recyclerView或者listView和ScrollView需要状态的情况也不在少数,测试发现
在activity中直接pageState = StatusLayout.wrap(this,R.id.id_of_scroll_view)类似这样的代码,在scrollView设置了权重的情况下,并不能加载scrollview正确的宽高。

原理很简单,原View被加载到了自定义View,自定义View获取了它的lp,但是原View的宽高这时候不应该都是MATCH_PARENT吗?

我懒得copy和paste,直接反射写了段。


    public static PageState wrap(Activity activity, @IdRes int contentId) {
        ViewGroup actContent = activity.findViewById(android.R.id.content);
        ViewGroup rootLayout = (ViewGroup) (actContent).getChildAt(0);
        View contentLayout = rootLayout.findViewById(contentId);
        if (contentLayout == null) {
            throw new RuntimeException("contentLayout can not be null");
        }
        ViewGroup.LayoutParams lp = contentLayout.getLayoutParams();
        ViewGroup parent = (ViewGroup) contentLayout.getParent();
        if (parent == null) {
            throw new RuntimeException("parent of the contentLayout can not be null");
        }
        int contentViewIndex = parent.indexOfChild(contentLayout);

        // 移除子View
        parent.removeView(contentLayout);

        // 添加statusView
        PageStateLayout statusLayout = new PageStateLayout(parent.getContext());
        parent.addView(statusLayout, contentViewIndex,lp);
        // statusView添加子View
        statusLayout.addView(contentLayout);

        // 设置宽高
        contentLayout.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
        contentLayout.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
        
        // 反射调用setContentView方法,将contentLayout设置为statusLayout的contentLayout
        Class<?> temp = statusLayout.getClass();
        Field f;
        try {
            f = temp.getDeclaredField("mPageStateCreator");
            f.setAccessible(true);
            Method get = f.get(statusLayout).getClass().getDeclaredMethod("setContentView", View.class);
            get.setAccessible(true);
            get.invoke(f.get(statusLayout),contentLayout);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return statusLayout;
    }
@mylhyl
Copy link
Owner

mylhyl commented Dec 16, 2019

@oOJohn6Oo 原View被加载到了自定义View,自定义View获取了它的lp,但是原View的宽高这时候不应该都是MATCH_PARENT吗?
不一定的,那得contentLayout的lp参数是啥样。
至于把contentLayout的lp用到PageStateLayout上,是保证不影响整个layout。
"scrollView设置了权重的情况下,并不能加载scrollview正确的宽高",这个问题还请提供layout布局代码,谢谢支持反馈!

@oOJohn6Oo
Copy link
Author

不是啊,你代码是一个FrameLayout作为父布局,多种状态的View和需要被wrap的targetView作为子View,然后把这个FrameLayout的LP替换为targetView的LP,直接添加到targetView原来parentView中,并且它在targetView的父布局中的位置不变,是吧。

原View也就是targetView,它现在的父布局是FrameLayout,为什么不是MATCH_PARENT?
‘scrollView设置了权重...’,也是这个问题导致的。

另外这个有个明显的问题就是不能处理CoordinatorLayout的情况,我后来想想自己写了个,直接替换父布局中的targetView,而不是插入FrameLayout,这样可以兼容所有情况。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants