LayoutInflater

2020-08-20  本文已影响0人  陈萍儿Candy

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);
    }
上一篇下一篇

猜你喜欢

热点阅读