Android 视图如何在屏幕上占据空间
如果视图宽度是固定的,我想计算一次屏幕上显示多少视图。为此,我得到一个布局,在其中添加一些固定大小的视图并运行它 但根据我的计算,我在屏幕上显示的孩子数量是错误的 请告诉我哪里错了 这是我的密码Android 视图如何在屏幕上占据空间,android,android-layout,Android,Android Layout,如果视图宽度是固定的,我想计算一次屏幕上显示多少视图。为此,我得到一个布局,在其中添加一些固定大小的视图并运行它 但根据我的计算,我在屏幕上显示的孩子数量是错误的 请告诉我哪里错了 这是我的密码 In Activity ... ---- LinearLayout featured_listlayout_horizontallayout=(LinearLayout)findViewById(R.id.featured_listlayout_horizontallayout)
In Activity ...
----
LinearLayout featured_listlayout_horizontallayout=(LinearLayout)findViewById(R.id.featured_listlayout_horizontallayout);
LayoutInflater inflater=LayoutInflater.from(getApplicationContext());
for(int i=0;i<20;i++){
LinearLayout childItem=(LinearLayout)inflater.inflate(R.layout.childitemlayout,null);
Button btn=(Button)childItem.findViewById(R.id.btn);
btn.setText("Item"+(i+1));
featured_listlayout_horizontallayout.addView(childItem);
}
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
final int height = dm.heightPixels;
float screenWidth = dm.widthPixels;//Screen Width in pixel
float itemWidth=getResources().getDimension(R.dimen.featured_text);//itemWidth in DP
itemWidth=convertDpToPixel(itemWidth, getApplicationContext());// convert itemWidth into pixel
System.out.println("screenWidth "+screenWidth+" itemWidth "+itemWidth);
float noOfItem=screenWidth/itemWidth;
System.out.println("noOfItem "+noOfItem);
-----
convertPixelsToDp method:
public float convertPixelsToDp(float px,Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return dp;
}
convertDpToPixel method:
public float convertDpToPixel(float dp,Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * (metrics.densityDpi/160f);
return px;
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/featured_listlayout_horizontallayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dp" >
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
childitemlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/featured_text"
android:layout_height="@dimen/featured_image"
android:orientation="vertical"
android:background="#0000ff">
<Button android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Button"
android:background="#ff00ff"/>
</LinearLayout>
dimen.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="featured_text">80dp</dimen>
<dimen name="featured_image">60dp</dimen>
</resources>
在活动中。。。
----
LinearLayout特色\u listlayout\u horizontallayout=(LinearLayout)findViewById(R.id.featured\u listlayout\u horizontallayout);
LayoutFlater充气器=LayoutFlater.from(getApplicationContext());
对于(int i=0;i
但根据我的计算,我得到了错误的孩子人数显示
屏幕上显示的屏幕
你可以得到:
对于项目的宽度,可以得到以像素为单位的宽度,但也可以将其转换为dp
:
float itemWidth=getResources().getDimension(R.dimen.featured_text);
itemWidth=convertPixelsToDp(itemWidth, getApplicationContext());
然后尝试将这两个值一起使用
使用像素
或dp
编辑2:
您应该真正了解LayoutInflater
类的inflate()
方法。您需要使用适当的LayoutParams
对视图进行充气,这是通过提供作为充气布局文件父级的ViewGroup
来完成的。因此,您需要执行以下操作:
LinearLayout childItem = (LinearLayout) inflater.inflate(
R.layout.aaaaaaaaaaaa, featured_listlayout_horizontallayout, false);
如果不这样做,膨胀视图将不会具有设置的大小(正如您可能看到的那样,它们将包装其内容)。完成上述修改后,您希望在实际将其添加到布局中之前找出可见(全部或部分)的子视图数(使用您在xml布局中设置的维度)您只需将屏幕宽度除以资源中的维度:
int screenWidth = dm.widthPixels;
int itemWidth=getResources().getDimension(R.dimen.featured_text);
int noOfItem=screenWidth/itemWidth;
// if we have a remainder from the division it means there is extra space
// so we need to check if we have more items so there is another child partially showing
int rem = screenWidth % itemWidth;
if (rem != 0) {
noOfItem += 1;
}
编辑1:
您当前的代码无法工作,您不理解我的答案。dm.widthPixels
返回屏幕宽度(您的HorizontalScrollView
以像素为单位填充)。getResources().getDimension(R.dimen.featured\u text)
将以像素为单位返回该维度资源的值。不需要方法来转换这些值,只需直接使用它们即可。即使如此,您的代码也无法正常工作,因为您没有注意为视图指定正确的布局参数。您应该像这样展开子布局:
LinearLayout childItem = (LinearLayout) inflater.inflate(
R.layout.aaaaaaaaaaaa, featured_listlayout_horizontallayout, false);
此外,我只需使用下面的代码(在onCreate
方法中使用)来查找屏幕上可见的子项(完全可见或部分可见):
featured\u listlayout\u horizontallayout.post(新的Runnable(){
@凌驾
公开募捐{
DisplayMetrics dm=新的DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
//屏幕宽度
最终浮动屏幕宽度=dm.widthPixels;
最终整数计数=特色列表布局水平布局
.getChildCount();
int realWidth=0;
int visibleChildren=0;
for(int i=0;i
在将像素转换为dp时,为什么要除以160?正确的方法是dp=px/metrics.density;
@AleksG:这是不正确的,我是从android文档得到的,请参见这里的密度独立像素(dp)。这里是公式px=dp*(dpi/160),它是dp到px的转换,px到dp的转换公式是dp=px/(dpi/160)。我从我的工作代码中复制/粘贴了我的公式:)getResources().getdimen(R.dimen.text);此方法返回维度值乘以适当的度量值。因此,在这里我不需要将其转换为dp。我现在正在更新代码中的两个值(ScreenWidth和itemWidth)以像素为单位。但它仍然没有给出正确的计数。更新方式为…~float screenWidth=dm.widthPixels;//像素中的屏幕宽度float itemWidth=getResources().getDimension(R.dimen.Characterized_text);//DP itemWidth=convertDpToPixel中的itemWidth(itemWidth,getApplicationContext());//将itemWidth转换为PixelOweam,这是我想要的。但我只想知道如何在添加到布局之前获得此计数。因为基于此,我需要在其上添加填充。此外,我还有一个问题final View child=featured\u listlayout\u horizontallayout.getChildAt(I);realWidth+=child.getWidth();
这里child.getWidth()给我的宽度与我在xml中设置的宽度不同。为什么会这样?如果我在这里使用LinearLayout childItem=(LinearLayout)充气器。充气(R.layout.childitemlayout,null);
那么它会给我不同的宽度,如果我设置LinearLayout childItem=(LinearLayout)充气机。充气(R.layout.childitemlayout,特色的_listlayout _horizontallayout,true);
然后它会给我不同的宽度[这是我设置为查看的正确宽度]。你能解释为什么会这样吗?谢谢Luksprog的帮助。我接受你的答案。对于充气机,我从这里阅读Android文档,Android.view.ViewGroup)。但我不清楚充气机使用的布局参数。你能把我引向正确的方向吗。
LinearLayout childItem = (LinearLayout) inflater.inflate(
R.layout.aaaaaaaaaaaa, featured_listlayout_horizontallayout, false);
featured_listlayout_horizontallayout.post(new Runnable() {
@Override
public void run() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// screen width
final float screenWidth = dm.widthPixels;
final int count = featured_listlayout_horizontallayout
.getChildCount();
int realWidth = 0;
int visibleChildren = 0;
for (int i = 0; i < count; i++) {
final View child = featured_listlayout_horizontallayout
.getChildAt(i);
realWidth += child.getWidth();
if (realWidth < screenWidth) {
visibleChildren++;
} else {
visibleChildren++;
break;
}
}
// visibleChildren now has the visible children on the screen
}
});