美文网首页
LayoutInflater

LayoutInflater

作者: 陈萍儿Candy | 来源:发表于2020-08-20 14:12 被阅读0次

    1.inflate方法

    public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
            return inflate(resource, root, root != null);
        }
    
    if (TAG_MERGE.equals(name)) {
                        if (root == null || !attachToRoot) {
                            throw new InflateException("<merge /> can be used only with a valid "
                                    + "ViewGroup root and attachToRoot=true");
                        }
    
                        rInflate(parser, root, inflaterContext, attrs, false);
                    } else {
                        // Temp is the root view that was found in the xml
                        final View temp = createViewFromTag(root, name, inflaterContext, attrs);
    
                        ViewGroup.LayoutParams params = null;
    
                        if (root != null) {
                            if (DEBUG) {
                                System.out.println("Creating params from root: " +
                                        root);
                            }
                            // Create layout params that match root, if supplied
                            params = root.generateLayoutParams(attrs);
                            if (!attachToRoot) {
                                // Set the layout params for temp if we are not
                                // attaching. (If we are, we use addView, below)
                                temp.setLayoutParams(params);
                            }
                        }
    
                        if (DEBUG) {
                            System.out.println("-----> start inflating children");
                        }
    
                        // Inflate all children under temp against its context.
                        rInflateChildren(parser, temp, attrs, true);
    
                        if (DEBUG) {
                            System.out.println("-----> done inflating children");
                        }
    
                        // We are supposed to attach all the views we found (int temp)
                        // to root. Do that now.
                        if (root != null && attachToRoot) {
                            root.addView(temp, params);
                        }
    
                        // Decide whether to return the root that was passed in or the
                        // top view found in xml.
                        if (root == null || !attachToRoot) {
                            result = temp;
                        }
                    }
    

    2.fragment

    public class HomeCombinationFragment extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            // container 写不写都一样,布局没有改变 布局中设置高度这些都没有影响
            View view = inflater.inflate(R.layout.fragment_home_combination,container,false);
            return view;
        }
    }
    
    

    3.recyclerView

    @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
              //  没有传viewGroup 无法加载layout.xml中的params,比如宽高,margin等
                View view = LayoutInflater.from(context).inflate(R.layout.item_smoth_num_layout,null);
                return new MyViweHolder(view);
            }
    
    @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                // 正确的
                View view = LayoutInflater.from(context).inflate(R.layout.item_smoth_num_layout,viewGroup,false);
                return new MyViweHolder(view);
            }
    

    错误

    @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                // 传viewGroup  没有设置attachToRoot为false  报错
                View view = LayoutInflater.from(context).inflate(R.layout.item_smoth_num_layout,viewGroup);
                return new MyViweHolder(view);
            }
    

    如下是错误日志

    2020-07-31 16:21:32.955 30175-30175/com.example.uxin.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.uxin.myapplication, PID: 30175
        java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
            at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6796)
            at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5975)
            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
            at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
            at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
            at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
            at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924)
            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3641)
            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4194)
            at android.view.View.layout(View.java:19692)
    

    5.如果fragment设置为attachToroot为true,会出现栈溢出;

    public class HomeCombinationFragment extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            // 栈溢出
            View view = inflater.inflate(R.layout.fragment_home_combination,container);
            return view;
        }
    }
    
    

    栈溢出

    2020-07-31 15:35:11.377 26996-26996/com.example.uxin.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.uxin.myapplication, PID: 26996
        java.lang.StackOverflowError: stack size 8MB
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6958)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:6962)
    
    

    6.这个我fragment没有获取不到出现的问题,比如getItem方法返回的为null

    2020-07-31 14:16:16.063 8711-8711/com.example.uxin.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.uxin.myapplication, PID: 8711
        java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
            at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:396)
            at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:391)
            at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:107)
            at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1010)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1158)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1092)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1622)
            at android.view.View.measure(View.java:22104)
            at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227)
            at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1572)
            at android.view.View.measure(View.java:22104)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6584)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
            at android.view.View.measure(View.java:22104)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6584)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
            at android.view.View.measure(View.java:22104)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6584)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
            at com.android.internal.policy.DecorView.onMeasure(DecorView.java:722)
            at android.view.View.measure(View.java:22104)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2447)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1528)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1781)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1416)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6845)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
            at android.view.Choreographer.doCallbacks(Choreographer.java:778)
            at android.view.Choreographer.doFrame(Choreographer.java:713)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
            at android.os.Handler.handleCallback(Handler.java:789)
            at android.os.Handler.dispatchMessage(Handler.java:98)
            at android.os.Looper.loop(Looper.java:164)
            at android.app.ActivityThread.main(ActivityThread.java:6798)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    
    
    image.png

    7.自定义view中,如果view继承的是LinearLayout等ViewGroup,为了减少层级,自定义view中的布局的跟布局可以用merge;

    public class MyCommonView extends LinearLayout implements ICommonView {
    
       
        public MyCommonView(Context context) {
            this(context, null);
    
        }
    
        public MyCommonView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyCommonView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mContext = context;
            //此时 root必须填this,attachToRoot必须为true才可以把布局中inflate的view,addView到自定义view中,进而展示在界面视图中;
            // 可以把item_radio_player_layout布局的跟布局设置为merge,减少一个层级,但是如果该为merge,在跟布局上的padding设置将会不起作用,需要代码设置padding
            View view = LayoutInflater.from(context).inflate(R.layout.item_radio_player_layout, null, true);
        }
    
        }
    

    原始布局xml,跟布局有padding设置

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:paddingLeft="12dp"
        android:paddingRight="12dp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp">
    
        <include android:id="@+id/pwcv_cover_view"
            layout="@layout/view_radio_player_cover_layout"/>
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_toRightOf="@id/pwcv_cover_view"
            android:orientation="vertical">
    
          ......省略
    
        </LinearLayout>
    
    </LinearLayout>
    

    如果把LinearLayout该为merge,布局中padding设置将失效,需要代码设置padding

    public MyCommonView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mContext = context;
            // 可以把item_radio_player_layout布局的跟布局设置为merge,减少一个层级
           View view = LayoutInflater.from(context).inflate(R.layout.item_radio_player_layout, this, true);
            int i = CommonUtils.dip2px(mContext, 12);
    // 设置padding
            setPadding(i,i,i,i);
        }
    

    相关文章

      网友评论

          本文标题:LayoutInflater

          本文链接:https://www.haomeiwen.com/subject/lvxdrktx.html