界面精确布局的探究
来源:互联网 发布:three.js注释库 编辑:程序博客网 时间:2024/05/16 12:02
界面精确布局的探究
在多布局的时候会有这样的困扰,设置dp值使蒙层布局能够纹丝合缝的覆盖掉底层,但是宽屏手机如:魅族、华为荣耀,小屏手机如:oppo。总会出现覆盖的图“走位”。设置dp值只能使多数手机适配,下面的方法会让所有的手机都能适配。
实施步骤
1 找到底层布局的left,top,由于get*()方法在sign控件界面加载出来前为零,咱们略作延迟,Handler post延迟时间为
SystemClock.uptimeMillis()
+delaytimenew Handler().postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub sign.getLocationOnScreen(loaction); left = sign.getLeft(); top = sign.getTop(); right = sign.getRight(); bottom = sign.getBottom(); statusH = 60;//60为状态栏的高度,为了适配不同的手机,动态获取。demo中是在普通activity中拿的值。 signDialog = new SignGuideDialog(mActivity,R.layout.layout_guide_sign); signDialog.show(); //GuideControlUtil.getInstance(mActivity).setFinishShowSignGuide(); //signDialog.setDialogViewClick(this); } }, 100);
也可以在onWindowFocusChanged(boolean hasfocus)中得到这些值,不需要Handler。另外一种情况就是需要覆盖的View可能位置会被移动,再去执行sign.getLocationOnScreen(loaction);
得到的结果与之前没有移动的时候取得的值相同。这里面还包含状态栏的高度。在精确的计算中还得减去这部分。
解决的方法是,为该View添加监听
ViewTreeObserver vto = imageView.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); imageView.getHeight();imageView.getWidth();imageView.getTop();} });
ViewTreeObserver是专门监听绘图回调的,我们在每次监听前remove前一次的监听,避免重复监听。
2 将left,top传给蒙层,设置蒙层的layoutparams。
public void initLayout(){ ImageView imgRect = (ImageView) findViewById(R.id.guide_sign); int left = UnLoginSignDialog.left; int right = UnLoginSignDialog.right; int top = UnLoginSignDialog.top; int bottom = UnLoginSignDialog.bottom; int[] loaction = UnLoginSignDialog.loaction; LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(right-left, bottom-top); //当然也可以用imgRect.getLayoutParams得到布局文件中的属性,修改部分属性后,imgRect.setLayoutParams params.leftMargin = loaction[0]; params.topMargin = loaction[1]-UnLoginSignDialog.statusH; imgRect.setLayoutParams(params);}
延伸扩展
得到状态栏高度
private int getStatusLayerHeight(){ Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; return statusBarHeight; }
得到标题栏高度
private void getTitleLayerHeight(){ int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop(); //statusBarHeight是上面所求的状态栏的高度 int titleBarHeight = contentTop - getStatusLayerHeight();}
得到全屏高度
private static DisplayMetrics sDisplayMetrics;public static void init(Context context) { sDisplayMetrics = context.getResources().getDisplayMetrics(); checkScreen();}/** * 获取屏幕宽度 单位:像素 * * @return 屏幕宽度 */public static int getWidthPixels() { return sDisplayMetrics.widthPixels;}/** * dp 转 px * * @param dp dp值 * @return 转换后的像素值 */public static int dp2px(int dp) { return (int) (dp * sDisplayMetrics.density + ROUND_DIFFERENCE);}/** * dp 转 px * * @param dp dp值 * @return 转换后的像素值 */public static float dp2px(float dp) { return dp * sDisplayMetrics.density + ROUND_DIFFERENCE;}/** * px 转 dp * * @param px px值 * @return 转换后的dp值 */public static int px2dp(int px) { return (int) (px / sDisplayMetrics.density + ROUND_DIFFERENCE);}
许多手机有NavigationBar,有些是在屏幕下方,有些是在实体键盘中,这部分也会算入屏幕大小。这样会造成布局控件在onMeasure()方法操作有误差。故需要判断是否存在,如果存在那么高度几何
是否存在NavigationBar
private static boolean checkDeviceHasNavigationBar(Context context) {boolean hasNavigationBar = false;Resources rs = context.getResources();int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");if (id > 0) {hasNavigationBar = rs.getBoolean(id);}try {Class systemPropertiesClass = Class.forName("android.os.SystemProperties");Method m = systemPropertiesClass.getMethod("get", String.class);String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");if ("1".equals(navBarOverride)) {hasNavigationBar = false;} else if ("0".equals(navBarOverride)) {hasNavigationBar = true;}} catch (Exception e) {Log.w(TAG, e);}return hasNavigationBar;}
- 获取NavigationBar的高
private static int getNavigationBarHeight(Context context) { int navigationBarHeight = 0; Resources rs = context.getResources(); int id = rs.getIdentifier("navigation_bar_height", "dimen", "android"); if (id > 0 && checkDeviceHasNavigationBar(context)) { navigationBarHeight = rs.getDimensionPixelSize(id); } return navigationBarHeight;}
7/2/2015 9:26:41 AM
0 0
- 界面精确布局的探究
- ExpandableListView 功能界面布局探究之一 ( 更换ExpandableListView右边的箭头(小图标))
- ExpandableListView 功能界面布局探究之二(只展开一个group的实现)
- ExpandableListView 功能界面布局探究之一 ( 更换ExpandableListView右边的箭头(小图标))
- ExpandableListView 功能界面布局探究之三(没有child的下拉列表,group不展开的实现)
- Android的界面布局
- Android LinearLayout布局的layout_weight属性探究
- JAVA的界面布局原理
- c#的WinForm界面布局
- Android界面布局的优化
- 界面布局TabBar的应用
- c#的WinForm界面布局
- 安卓几种界面布局的详解
- 界面的布局(一)
- 界面布局
- 界面布局
- 界面布局
- Windows Phone canvas精确布局
- css纯代码实现圆边框和圆按钮
- 如何打开Oracle的dmp文件
- 基于xslt的简单应用开发
- 一个页面多个倒计时
- JS+CSS实现Dock menu(Mac菜单导航效果)
- 界面精确布局的探究
- linux,下shell的if..fi
- 黑马程序员——Java基础-------面向对象(二)
- 如何查看数据库是多少位--DZY
- java web开发 高并发处理
- 主流PHP博客系统比较
- [转]SQL分组查询及聚集函数的使用
- 使用FFMPEG制作GIF
- 软件设计之——“高内聚低耦合”