您的位置:首页 > 新闻 > 资讯 > 电商网站模板建站_收录之家_企业网络推广计划_公众号开发网站公司

电商网站模板建站_收录之家_企业网络推广计划_公众号开发网站公司

2024/12/22 19:44:50 来源:https://blog.csdn.net/moy1995/article/details/142913159  浏览:    关键词:电商网站模板建站_收录之家_企业网络推广计划_公众号开发网站公司
电商网站模板建站_收录之家_企业网络推广计划_公众号开发网站公司

一开始项目使用的是第三方框架

GitHub - JessYanCoding/AndroidAutoSize: 🔥 A low-cost Android screen adaptation solution (今日头条屏幕适配方案终极版,一个极低成本的 Android 屏幕适配方案).

但是会偶现,断电重启第一次,自适应失败的情况。

复现手顺:

当前为A分辨率,杀死进程 =》设置B分辨率=》断电重启,自适应失败。

以下内容基于单位dp。

一 失败原因

第一种

设置DisplayMetrics还未生效,layout已经开始绘制,导致失败。

第二种

DisplayMetrics是全局可用,被其他应用【三方应用或者系统应用\View等】重写了甚至是恢复默认,导致失败。

二 原理

DisplayMetrics是公用的,谁都有权利进行修改,DisplayMetrics.density一旦进行修改,所有的页面、view、第三方库都会被修改到。

能够达到低成本和低侵入性。

同时如果,其他应用,或者系统进行DisplayMetrics.density的修改,也会影响到我们自身的应用。

除非我们的页面已经创建,没有重建,创建好的页面后,再设置density是不会成功的。

三 解决方案

工具类

public class DisplayUtils {private String TAG = DisplayUtils.class.getSimpleName();//设计宽度private static final float DEFAULT_DISPLAY_WIDTH = 1280;private static DisplayUtils instance = null;public synchronized static DisplayUtils getInstance() {if (instance == null) {instance = new DisplayUtils();}return instance;}//设计高度,本项目以高度为准,横向滑动private float DEFAULT_DISPLAY_HEIGHT = 720;public void setDisplayDensity(Context context){if (context == null) {Log.d(TAG, "context is null");return;}DisplayMetrics displayMetrics = getRealDisplayMetrics(context);//布局缩放倍数float targetDensity = ((float) displayMetrics.heightPixels) / DEFAULT_DISPLAY_HEIGHT;//todo 宽度为基准
//        float targetDensity = ((float) displayMetrics.widthPixels) / DEFAULT_DISPLAY_WIDTH;//字体缩放倍数float targetScaledDensity = targetDensity * (displayMetrics.scaledDensity / displayMetrics.density);int targetDensityDpi = (int) (targetDensity * 160);Log.d(TAG, "setDisplayDensity: heightPixels = " + displayMetrics.heightPixels +", targetDensity = "+ targetDensity + ", density = " + displayMetrics.density + ", scaledDensity = " + displayMetrics.scaledDensity+ ", targetScaledDensity = " + targetScaledDensity + ", targetDensityDpi = " + targetDensityDpi);DisplayMetrics activityDisplayMetrics = context.getResources().getDisplayMetrics();activityDisplayMetrics.density = targetDensity;activityDisplayMetrics.densityDpi = targetDensityDpi;activityDisplayMetrics.scaledDensity = targetScaledDensity;}public static DisplayMetrics getRealDisplayMetrics(Context context){DisplayMetrics displayMetrics = new DisplayMetrics();WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = windowManager.getDefaultDisplay();display.getRealMetrics(displayMetrics);return displayMetrics;}/*** 每个子fragment创建之前重置density,保证是正确的,因为onConfigurationChanged回调分辨率切换时设置后,* 在Fragment创建前density又被系统修改,导致分辨率显示异常(偶现)*/public void setDisplayDensityForFragments(AppCompatActivity context){context.getSupportFragmentManager().registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {@Overridepublic void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {super.onFragmentCreated(fm, f, savedInstanceState);Log.d(TAG, "onFragmentCreated: " + f);setDisplayDensity(context);}}, true);}
}

使用方式

Activity

以下为主Activity调用,必须在setContentView之前。在view绘制之前需要设置好DisplayMetrics.density。

要注意onConfigurationChanged里,分辨率差距过小,页面可能不会进行重建,这个时候需要我们手动重建。

@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {DisplayUtils.getInstance().setDisplayDensity(this);DisplayUtils.getInstance().setDisplayDensityForFragments(this);super.onCreate(savedInstanceState);setContentView(R.layout.xxxx);}@Overridepublic void onConfigurationChanged(@NonNull Configuration newConfig) {super.onConfigurationChanged(newConfig);Log.e(TAG, "onConfigurationChanged screenInfo Width:" + ScreenUtils.getScreenWidth() + " height:" + ScreenUtils.getScreenHeight() + " dpi:" + ScreenUtils.getScreenDensityDpi());DisplayUtils.getInstance().setDisplayDensity(this);//偶现分辨率不会重绘,手动重绘this.recreate();}

Fragment

在主Activity添加“ DisplayUtils.getInstance().setDisplayDensityForFragments(this);”这句代码后,本身Fragment是不需要单独设置的。

因为我们项目是只有一个activity,剩下的都是Fragment,时序问题导致,偶现首个添加的Fragment自适应失败,所以才需要单独添加代码。

同样也需要在设置view之前,但是不能在onCrate,请参考第二种情况的原因。

为了保证自适应一定成功,要在页面显示到屏幕之前,毫秒级别的差距,设置成你想要的DisplayMetrics.density。否则就有可能会失败。

@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {DisplayUtils.getInstance().setDisplayDensity(getMainActivity());binding = DataBindingUtil.inflate(inflater, R.layout.xxxx, container, false);return binding.getRoot();}

动态添加View的时候,最好也设置一下。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com