换肤效果实现

本文详细介绍了如何实现Android应用的换肤功能,包括通过拦截系统创建View收集换肤控件,以及通过反射加载外部皮肤包。关键在于实现LayoutInflater.Factory2接口以拦截View创建,并利用AssetManager加载外部资源。
摘要由CSDN通过智能技术生成

apk换肤在有些app上实现的还不错,比如QQ,网易云等;那怎么去实现一个无闪烁,无启动的换肤呢?
接下来从代码角度一步一步去实现app的换肤功能

要想实现真正换肤的话,首先要面临两个问题;首先是怎么知道哪些控件是需要换肤的?然后换肤的资源包是怎么从外部加载进来的?
在这里插入图片描述

拦截系统创建收集需要换肤的View

如上图所示,首先我们要做的是拦截系统实例化View的过程,自己创建View,收集需要换肤的View;那怎么去拦截呢?我们知道android 的页面大部分是通过布局文件xml来编写的,那系统是怎么解析这个xml的呢?
我们从AppCompatActivity->setContentView方法看起:

  @Override
    public void setContentView(@LayoutRes int layoutResID) {
   
        getDelegate().setContentView(layoutResID);
    }

可以看到它调用到了AppCompatDelegateImpl的setContentView方法:

    @Override
    public void setContentView(int resId) {
   
        ensureSubDecor();
        ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
        contentParent.removeAllViews();
        LayoutInflater.from(mContext).inflate(resId, contentParent);
        mAppCompatWindowCallback.getWrapped().onContentChanged();
    }

我们看到它是通过LayoutInflater加载的,最终它会走到LayoutInflater的inflate方法:

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
   
        synchronized (mConstructorArgs) {
   
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");

            final Context inflaterContext = mContext;
            final AttributeSet attrs = Xml.asAttributeSet(parser);
       		//代码省略///
            try {
   
        
                if (TAG_MERGE.equals(name)) {
   
       				//关键解析代码
                    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);
                        }
            
                    // Inflate all children under temp against its context.
                    //关键代码//
                    rInflateChildren
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值