Проблемы с вертикальным выравниванием Button и горизонтально ориентированным LinearLayout внутри вертикально ориентированного LinearLayout - PullRequest
0 голосов
/ 11 июля 2010

Я пишу со своего телефона, так что прошу прощения за глупые опечатки и проблемы с форматированием.

У меня есть действие, в котором перечислены сохраненные игры, которые игрок может загрузить.

Я создал простой XML-файл макета, который определяет ScrollView. При загрузке я беру все сохраненные игры и программно добавляю представление для каждой сохраненной игры в вертикально ориентированный дочерний элемент LinearLayout ScrollView.

Представление для каждой игры состоит из горизонтально ориентированного 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

Моя проблема:

Я бы хотел, чтобы верхняя часть кнопки и текстовое представление "название игры" были выровнены по вертикали, но у 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 ]

3 голосов
/ 12 июля 2010

Если вы хотите какое-либо выравнивание, почему бы вам не использовать RelativeLayout?Это в основном предназначено для выравнивания одного вида с другим.android: layout_alignTop звучит как то, что вы хотите.

(И, конечно, убедитесь, что значения заполнения одинаковы во всех элементах управления, но я уверен, что вы это сделали.)

2 голосов
/ 12 июля 2010

Почему бы вам не попробовать использовать ListView для такого типа графического интерфейса.

Вам все равно нужно будет определить строку xml.

1 голос
/ 12 июля 2010

+ 1 к ответам, предлагающим ListView и RelativeLayout. Для этого типа ситуации вы, вероятно, хотите ListView с макетом элемента, используя RelativeLayout. (ListView будет масштабироваться намного лучше, если будет много элементов, и если это для списка сохраненных игр, кажется, что он может немного вырасти.) Для этого типа пользовательского интерфейса рекомендуется, чтобы весь элемент строки / списка был активным для нажатия чем использовать маленькую кнопку «Загрузить», но это вопрос дизайна и, в конечном итоге, решать вам.

Не используйте getApplicationContext для создания ваших представлений. Активность - это контекст, просто передайте this в вашем случае.

По умолчанию LinearLayouts пытается выровнять дочерние представления по их текстовой базовой линии, если таковая имеется. Обратите внимание, что нижняя часть текста «Загрузить» вашей кнопки идеально совпадает с текстом CURRENT_GAME на снимке экрана. Попробуйте gameContainer.setBaselineAligned(false).

Обычно ваш макет gameInfo сообщает о базовой линии только одного из его дочерних элементов, если вы установите baselineAlignedChildIndex, но похоже, что это поведение изменилось между cupcake и eclair при программном создании LinearLayouts. (Ссылка на коммит, который изменил его в AOSP здесь .)

...