我正在开发Android v2.2应用程序。
我有一个碎片。在我的片段类的onCreateView(…)回调中,我将一个布局膨胀到片段,如下所示:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.login, null);
return view;
}
上面的膨胀布局文件是(login.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Username" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Username" />
</LinearLayout>
我想设置一个paddingTop到上面的<LinearLayout>元素,我想在Java代码中做,而不是在xml中做。
如何设置paddingTop <LinearLayout>在我的片段Java类代码??
最好的方法是不要自己写函数。
让我解释一下动机——请查阅官方的Android源代码。
在TypedValue.java中,我们有:
public static int complexToDimensionPixelSize(int data,
DisplayMetrics metrics)
{
final float value = complexToFloat(data);
final float f = applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
value,
metrics);
final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
if (res != 0) return res;
if (value == 0) return 0;
if (value > 0) return 1;
return -1;
}
and:
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
正如你所看到的,DisplayMetrics指标可能不同,这意味着它将在Android-OS支持的设备上产生不同的值。
我强烈建议把你的dp填充在dimen xml文件中,并使用官方的Android转换,以保持与Android框架工作方式一致的行为。
使用Jave的解决方案。
public static int getResourceDimension(Context context, String name, String defType, String defPackage) {
int sizeInDp = 0;
int resourceId = context.getResources().getIdentifier(name, defType, defPackage);
if (resourceId > 0) {
sizeInDp = context.getResources().getDimensionPixelSize(resourceId);
}
float scale = context.getResources().getDisplayMetrics().density;
int dpAsPixels = (int) (sizeInDp*scale + 0.5f);
return dpAsPixels;
}
然后在需要的时候打电话。
int statusBarHeight = getResourceDimension(getContext(), "status_bar_height",
"dimen", "android");
statusBarHeight = (int) (statusBarHeight + getResources().getDimension(R.dimen.fragment_vertical_padding));
view.setPadding(0, statusBarHeight, 0, 0);
与手动计算相比,使用TypedValue是一种更清晰的转换为像素的方式:
float paddingDp = 10f;
// Convert to pixels
int paddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, paddingDp, context.getResources().getDisplayMetrics());
view.setPadding(paddingPx, paddingPx, paddingPx, paddingPx);
本质上,TypedValue。applyDimension根据当前设备的显示属性将所需的填充适当地转换为像素。
更多信息见:TypedValue。applyDimension文档。
芬兰湾的科特林;扩展函数
fun Float.px(m: DisplayMetrics!): Int
get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, m).toInt()
...
val pad = 10.0f.px