在垂直方向的LinearLayout中垂直对齐Button和水平方向的LinearLayout时出现问题

时间:2010-07-11 19:56:13

标签: android user-interface vertical-alignment

我在手机上发帖,请原谅错误的拼写错误和格式化问题。

我有一个列出玩家可以加载的已保存游戏的活动。

我创建了一个简单的布局xml文件,它定义了一个ScrollView。在加载时,我抓取所有已保存的游戏并以编程方式将每个已保存游戏的视图添加到ScrollView的垂直方向的LinearLayout子级。

每个游戏的视图由水平定向的LinearLayout组成,而LinearLayout又包含一个Button和一个垂直方向的LinearLayout。那个LinearLayout又包含一些TextViews和ImageViews(以及为了清楚起见,我在这里省略了一个LinearLayout)。

层次结构看起来像这样(省略了一些细节)。

 ScrollView
      LinearLayout - vertical 
           Each saved game:
           LinearLayout - horizontal 
                Button - load game
                LinearLayout - vertical 
                     TextView - game name
                     TextView - date string

我的问题:

我希望按钮的顶部和“游戏名称”texview垂直对齐,但TextView(或者它的LinearLayout父级)在顶部有一些我无法摆脱的流氓填充。有关详情,请参见截图

alt

LoadSaved类: 注意:mScrollView命名错误。它指的是ScrollView的子LinearLayout。

   public class LoadSaved extends Activity {
     public LinearLayout mScrollView;
     private MinerDb mDb;

      public void onCreate(Bundle b) { 
             super.onCreate(b);
             setContentView(R.layout.loadsaved);
             mDb = new MinerDb(this);

            mScrollView = (LinearLayout) findViewById(R.id.load_scroll_view);
            Bundle[] savedGames = mDb.getSavedGames();

            for (int i = 0; i < savedGames.length; i++) {
                 Bundle game = savedGames[i];

                 final int gameId = game.getInt("gameId");
                 String name = game.getString("name");
                 String date = game.getString("date");

                 Bundle player = game.getBundle("player");
                 int playerMoney = player.getInt("money");
                 int playerHealth = player.getInt("health");

                 LinearLayout gameContainer = new LinearLayout(getApplicationContext());
                 gameContainer.setPadding(5, 5, 5, 5);
                 gameContainer.setGravity(Gravity.TOP);
                 gameContainer.setOrientation(LinearLayout.HORIZONTAL);
                 gameContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

                 Button loadButton = new Button(getApplicationContext());
                 loadButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                 loadButton.setText("Load");


                 LinearLayout gameInfo = new LinearLayout(getApplicationContext());
                 gameInfo.setOrientation(LinearLayout.VERTICAL);
                 gameInfo.setPadding(10,0,10,10);
                 gameInfo.setGravity(Gravity.TOP);
                 gameInfo.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

                 TextView nameView = new TextView(getApplicationContext());
                 nameView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
                 nameView.setGravity(Gravity.TOP);
                 nameView.setText(name);

                 TextView dateView = new TextView(getApplicationContext());
                 dateView.setPadding(5,0,0,0);
                 dateView.setGravity(Gravity.TOP);
                 dateView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
                 dateView.setText(date);

                 LinearLayout playerView = new LinearLayout(getApplicationContext());
                 playerView.setOrientation(LinearLayout.HORIZONTAL);
                 playerView.setPadding(5,0,0,0);
                 playerView.setGravity(Gravity.TOP);
                 playerView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

                 TextView playerMoneyView = new TextView(getApplicationContext());
                 playerMoneyView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                 playerMoneyView.setPadding(0,0,10,0);
                 playerMoneyView.setTextColor(Color.GREEN);
                 playerMoneyView.setText("$" + playerMoney);

                TextView playerHealthView = new TextView(getApplicationContext());
                playerHealthView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                playerHealthView.setPadding(0,0,10,0);
                playerHealthView.setTextColor(Color.RED);
                playerHealthView.setText(playerHealth + "%");

                playerView.addView(playerMoneyView);
                playerView.addView(playerHealthView);

                gameInfo.addView(nameView);
                gameInfo.addView(dateView);
                gameInfo.addView(playerView);

                gameContainer.addView(loadButton);
                gameContainer.addView(gameInfo);

                mScrollView.addView(gameContainer);

                loadButton.setOnClickListener(new OnClickListener() { 
                     public void onClick(View v) {
                           Log.e("LoadSaved", "LoadSaved::onCreate: Clicking: " + gameId);
                           Intent loadGameIntent = new Intent(LoadSaved.this, Miner.class);
                           loadGameIntent.putExtra("load_game", gameId);
                           startActivity(loadGameIntent);
                           finish();
                      }
                 });
            }
       }
  }

loadsaved.xml                                      

           <LinearLayout
                android:orientation="vertical"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:id="@+id/load_scroll_view" />

       </ScrollView>
  </LinearLayout>

3 个答案:

答案 0 :(得分:3)

如果您想要任何对齐方式,为什么不使用RelativeLayout?这基本上是为了将一个视图与另一个视图对齐。 android:layout_alignTop听起来像你想要的东西。

(当然,验证所有控件中的填充值是否相同,但我确定你这样做了。)

答案 1 :(得分:2)

为什么不尝试将ListView用于那种gui。

您仍需要定义行xml。

答案 2 :(得分:1)

+1表示ListView和RelativeLayout的答案。对于这种情况,您可能需要使用RelativeLayout的项目布局的ListView。 (如果有很多项目,ListView会扩展得更好,如果这是一个已保存的游戏列表,看起来这可能会增长很多。)对于这种类型的UI,建议让整个行/列表项可点击而不是使用一个小的加载按钮,但这是一个设计问题,最终取决于你。

请勿使用getApplicationContext创建您的观看次数。活动是一个上下文,只需在您的案例中传递this

默认情况下,LinearLayouts尝试将子视图与其文本基线对齐(如果存在)。请注意,按钮的加载文本底部与屏幕截图中的CURRENT_GAME文本完全对齐。试试gameContainer.setBaselineAligned(false)

通常,如果设置baselineAlignedChildIndex,您的gameInfo布局将仅报告其子项的基线,但在以编程方式创建LinearLayouts时,看起来这种行为在cupcake和eclair之间发生了变化。 (链接到在AOSP here中更改它的提交。)