安卓屏幕适配

264 阅读2分钟

InflaterAuto 屏幕适配 超简单

欢迎大家阅读,学习

author 北纬34点8度 gtihub 地址:github.com/genius158/I…

概述 由LayoutInflater入手,更改获取布局解析服务的方法,返回我们自己的布局解析器,在创建View的完成时 ,就对View(包括子View,如果有)的LayoutParams进行调整,来做适配,这个步骤是在View开始测量绘制之前,不会造成二次 绘制,性能上除了View创建完成时对其递归调整LayoutParams之外,是没有任何影响的。

选择切入点

view的设置LayoutParams是在LayoutInflater的rInflate方法中执行的

void rInflate(XmlPullParser parser, View parent, Context context,
           AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {
    ...
    final View view = createViewFromTag(parent, name, context, attrs);
    final ViewGroup viewGroup = (ViewGroup) parent;
    final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
    rInflateChildren(parser, view, attrs, true);//这里是归调继续创建View
    viewGroup.addView(view, params);
    ...
    }

可以看到,LayoutParams是在这里创建的,这个方法是我们最需要更改操作的,然而我们并不能覆写这个方法,AndroidAutoLayout有一系列的Auto开头的ViewGroup ,其重写的也就是generateLayoutParams,直接返回调整过的params,然而它仍然需要在OnMeasure的时候对所有子View内部相关属性做调整, 如果想在rInflate方法里,在创建完View后直接做调整,需要我们完全重写LayoutInflater,然而一些内部方法,我们并不能使用,同时在 Android自身的升级过程中,这个类的各种更改,难以把控。最终还是选择在inflate返回View以后直接对View做调整,来实现适配。

使用

项目引用

在app下的bulid.gradle里dependencies下添加
implementation 'com.yan:inflaterauto:1.0.1'    OR   compile 'com.yan:inflaterauto:1.0.1'    
根据gradle版本不同 选择需要的

XML修改

布局宽度layout_width 高度layout_height 内边距android:paddingLeft 外边距android:layout_marginTop 值都用px设置(除ViewGroup)

JAVA代码修改

1、 修改application
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        //**初始化MyApplication时添加**
        InflaterAuto.init(new InflaterAuto.Builder(this)
            .width(720)
            .height(1280)//根据720*1280的UI作图,如果不是可修改
            .baseOnDirection(InflaterAuto.BaseOn.Both)// 宽度根据宽度比例缩放,长度根据长度比例缩放
            .addException(AppBarLayout.class)//add do not need adjust view type
            .build()
        );
    }


    /**
     * 如果你使用了LayoutInflater.from(getApplicationContext())或者LayoutInflater.from(getApplication())
     * 就需要以下操作,如果没有,以下方法不必重写
     */
    @Override
    protected void attachBaseContext(Context base) {
        //替换Inflater
        super.attachBaseContext(InflaterAuto.wrap(base));
    }
}
2、修改activity
public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //**如果app支持旋转 需在布局设置前加以下代码,同时保证界面正常销毁重新加载**
        InflaterAuto.getInstance().supportScreenRotation(savedInstanceState, this);
        setContentView(R.layout.activity_main);
    }
    //**需重写attachBaseContext**
    @Override
    protected void attachBaseContext(Context base) {
        //替换Inflater
        super.attachBaseContext(InflaterAuto.wrap(base));
    }
}