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
        }

    });