Android addRule RelativeLayout.BELOW无法正确呈现

时间:2014-06-12 11:50:48

标签: android android-layout relativelayout android-view

我想根据卡片数量动态膨胀RelativeLayout。出于测试目的,我将循环设置为3.但是当我运行代码时,我只能查看最后2张卡,而不是3.我在这里缺少什么?

请在下面找到截图和代码。

screenshot

fragment_wallet.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/splash1_bg"
    android:orientation="vertical" >

    <!-- ViewPager -->
    <!-- Navigation -->

    <android.support.v4.view.ViewPager
        android:id="@+id/wallet_viewPager"
        android:layout_width="match_parent"
        android:layout_height="130dp" >
    </android.support.v4.view.ViewPager>

    <include layout="@layout/wallet_dot" />

    <RelativeLayout
        android:id="@+id/wallet_card_wrapper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="bottom"
        android:layout_marginTop="130dp" >

    </RelativeLayout>

</FrameLayout>

wallet_card.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/wallet_card_header"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_margin="10dp"
    android:background="@drawable/top_rounded_corner" >

    <ImageView
        android:id="@+id/wallet_card_card_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:padding="10dp"
        android:src="@drawable/card_logo" />

    <TextView
        android:id="@+id/wallet_card_txtDistance"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:paddingRight="10dp"
        android:text="5m"
        android:textColor="@color/white" />

    <ImageView
        android:id="@+id/wallet_card_location_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/wallet_card_txtDistance"
        android:padding="5dp"
        android:src="@drawable/card_view_location_point" />

</RelativeLayout>

MyFragment.java

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_wallet);

        LayoutInflater layoutInflator = (LayoutInflater) getApplicationContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        RelativeLayout insertPoint = (RelativeLayout) findViewById(R.id.wallet_card_wrapper);
        List views = new ArrayList();

        for (int i = 0; i < 3; i++) {
            View view = layoutInflator.inflate(R.layout.wallet_card, null);
            TextView textView = (TextView) view
                    .findViewById(R.id.wallet_card_txtDistance);
            textView.setText("10" + i + "m");
            int height = (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
                            .getDisplayMetrics());
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, height);
            lp.addRule(RelativeLayout.BELOW, view.getId()); //<---- I THINK THE PROBLEM IS IN THIS LINE
            lp.setMargins(20, 20, 20, 0);
            view.setLayoutParams(lp);

            views.add(view);
        }

        System.out.println(views.size());
        for (int i = 0; i < views.size(); i++)
            insertPoint.addView((View) views.get(i));
    }

3 个答案:

答案 0 :(得分:2)

这是一个难看的修复方法,但我已经用Google搜索了4个小时而无法找到有效的解决方案,所以现在是时候进行难看的修复了。

第一和第二个元素重叠。出于某种原因,第二个元素不会放在第一个元素之下。但是,相同的代码将第三个元素放在第二个元素之下。所以,丑陋的修复是:添加一个假的第一个元素,它将与你真实的第一个元素重叠。

真的很糟糕。但我找不到其他有用的东西。

PS:您可能不应该将此标记为正确答案,即使它使您的代码有效。至少我不认为这是一个真正的答案,只是一个丑陋的补丁。

答案 1 :(得分:1)

你是对的:

in:

    lp.addRule(RelativeLayout.BELOW, view.getId()); 
    view.setLayoutParams(lp);

你告诉视图低于itsef(通过在addRule方法中传递自己的id)

我会尝试类似的事情:

 int lastId = -1;
 for (int i = 0; i < 3; i++) {
       View view = layoutInflator.inflate(R.layout.wallet_card, null);
       ... 
       RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, height);

       if(lastId >-1) 
           lp.addRule(RelativeLayout.BELOW, lastId);  //giving the previous view's id here
       lp.setMargins(20, 20, 20, 0);
       view.setLayoutParams(lp);

       views.add(view);

       lastId = view.getId(); //keep this view id for next iteration
 }

希望有所帮助

编辑:

同时删除android:layout_alignParentTop="true"

它会破坏“下方”规则,因为它不能同时在父上方对齐而在上一个视图下方

而是在父相对布局上使用android:layout_gravity="top",因此第一个视图将在父顶部对齐。 (有没有理由为gravity:bottom?)

答案 2 :(得分:0)

试试这种方式,希望这可以帮助您解决问题。

<强> fragment_wallet.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


    <android.support.v4.view.ViewPager
         android:id="@+id/wallet_viewPager"
         android:layout_width="match_parent"
         android:layout_height="130dp" >
    </android.support.v4.view.ViewPager>


    <LinearLayout
        android:id="@+id/wallet_card_wrapper"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">

    </LinearLayout>

</LinearLayout>

活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_wallet);
    LinearLayout insertPoint = (LinearLayout) findViewById(R.id.wallet_card_wrapper);
    ArrayList<View> views = new ArrayList<View>();

    for (int i = 0; i < 3; i++) {
        View view = LayoutInflater.from(this).inflate(R.layout.wallet_card, null, false);
        TextView textView = (TextView) view.findViewById(R.id.wallet_card_txtDistance);
        textView.setText("10" + i + "m");
        int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, height);
        lp.setMargins(20, 20, 20, 0);
        view.setLayoutParams(lp);

        views.add(view);
    }

    System.out.println(views.size());
    for (int i = 0; i < views.size(); i++)
        insertPoint.addView(views.get(i));
 }