Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

TableLayout и TableRow

Разметка TableLayout (Табличная разметка) позиционирует свои дочерние элементы в строки и столбцы, как это привыкли делать веб-мастера в теге table. TableLayout не отображает линии обрамления для их строк, столбцов или ячеек. TableLayout может иметь строки с разным количеством ячеек. При формировании разметки таблицы некоторые ячейки при необходимости можно оставлять пустыми. При создании разметки для строк используются объекты TableRow, которые являются дочерними классами TableLayout (каждый TableRow определяет единственную строку в таблице). Строка может не иметь ячеек или иметь одну и более ячеек, которые являются контейнерами для других объектов. В ячейку допускается вкладывать другой TableLayout или LinearLayout.

TableLayout удобно использовать, например, при создании логических игр типа Судоку, Крестики-Нолики и т.п.

Вот несколько правил для TableLayout. Во-первых, ширина каждой колонки определяется по наиболее широкому содержимому в колонке. Дочерние элементы используют в атрибутах значение match_parent. Атрибут TableRow для layout_height всегда wrap_content. Ячейки могут объединять колонки, но не ряды. Достигается слияние колонок через атрибут layout_span.

Если атрибуту android:stretchColumns компонента TableLayout присвоить значение "*", то содержимое каждого компонента TableRow может растягиваться на всю ширину макета.

Создаем таблицу прогноза погоды

Например, для создания таблицы прогноза погоды можно использовать следующий дизайн:

  • В первом ряду показать заголовок таблицы
  • Во втором ряду показать даты по типу календаря
  • В третьем ряду показать наибольшую температуру
  • В четвёртом ряду показать наименьшую температуру
  • В пятом ряду показать графику (дождь, снег, облачность, солнце)
Показать код (щелкните мышкой)

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tableLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:shrinkColumns="*"
    android:stretchColumns="*" >

    <TableRow
        android:id="@+id/tableRow4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal" >

        <TextView
            android:id="@+id/textView9"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_span="6"
            android:gravity="center"
            android:text="Weather Table"
            android:textSize="18dp"
            android:textStyle="bold"
            android:typeface="serif" >
        </TextView>
    </TableRow>

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView04"
            android:text="" >
        </TextView>

        <TextView
            android:id="@+id/TextView04"
            android:text="Feb 7"
            android:textStyle="bold"
            android:typeface="serif" >
        </TextView>

        <TextView
            android:id="@+id/TextView03"
            android:text="Feb 8"
            android:textStyle="bold"
            android:typeface="serif" >
        </TextView>

        <TextView
            android:id="@+id/TextView02"
            android:text="Feb 9"
            android:textStyle="bold"
            android:typeface="serif" >
        </TextView>

        <TextView
            android:id="@+id/TextView01"
            android:text="Feb 10"
            android:textStyle="bold"
            android:typeface="serif" >
        </TextView>

        <TextView
            android:id="@+id/textView1"
            android:text="Feb 11"
            android:textStyle="bold"
            android:typeface="serif" >
        </TextView>
    </TableRow>

    <TableRow
        android:id="@+id/tableRow2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView2"
            android:text="Day High"
            android:textStyle="bold" >
        </TextView>

        <TextView
            android:id="@+id/textView3"
            android:gravity="center_horizontal"
            android:text="28°F" >
        </TextView>

        <TextView
            android:id="@+id/textView4"
            android:gravity="center_horizontal"
            android:text="26°F" >
        </TextView>

        <TextView
            android:id="@+id/textView5"
            android:gravity="center_horizontal"
            android:text="23°F" >
        </TextView>

        <TextView
            android:id="@+id/textView6"
            android:gravity="center_horizontal"
            android:text="17°F" >
        </TextView>

        <TextView
            android:id="@+id/textView7"
            android:gravity="center_horizontal"
            android:text="19°F" >
        </TextView>
    </TableRow>

    <TableRow
        android:id="@+id/tableRow2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView2"
            android:text="Day Low"
            android:textStyle="bold" >
        </TextView>

        <TextView
            android:id="@+id/textView3"
            android:gravity="center_horizontal"
            android:text="15°F" >
        </TextView>

        <TextView
            android:id="@+id/textView4"
            android:gravity="center_horizontal"
            android:text="14°F" >
        </TextView>

        <TextView
            android:id="@+id/textView5"
            android:gravity="center_horizontal"
            android:text="3°F" >
        </TextView>

        <TextView
            android:id="@+id/textView6"
            android:gravity="center_horizontal"
            android:text="5°F" >
        </TextView>

        <TextView
            android:id="@+id/textView7"
            android:gravity="center_horizontal"
            android:text="6°F" >
        </TextView>
    </TableRow>

    <TableRow
        android:id="@+id/tableRow3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" >

        <TextView
            android:id="@+id/textView8"
            android:text="Conditions"
            android:textStyle="bold" >
        </TextView>

        <ImageView
            android:id="@+id/imageView1"
            android:src="@drawable/hot" >
        </ImageView>

        <ImageView
            android:id="@+id/imageView2"
            android:src="@drawable/pt_cloud" >
        </ImageView>

        <ImageView
            android:id="@+id/imageView3"
            android:src="@drawable/snow" >
        </ImageView>

        <ImageView
            android:id="@+id/imageView4"
            android:src="@drawable/lt_snow" >
        </ImageView>

        <ImageView
            android:id="@+id/imageView5"
            android:src="@drawable/pt_sun" >
        </ImageView>
    </TableRow>

</TableLayout>

В альбомной ориентации наша разметка будет выглядеть следующим образом

Программное создание TableLayout

Показать код (щелкните мышкой)

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TableLayout table = new TableLayout(this);

        table.setStretchAllColumns(true);
        table.setShrinkAllColumns(true);

        TableRow rowTitle = new TableRow(this);
        rowTitle.setGravity(Gravity.CENTER_HORIZONTAL);

        TableRow rowDayLabels = new TableRow(this);
        TableRow rowHighs = new TableRow(this);
        TableRow rowLows = new TableRow(this);
        TableRow rowConditions = new TableRow(this);
        rowConditions.setGravity(Gravity.CENTER);

        TextView empty = new TextView(this);

        // title column/row
        TextView title = new TextView(this);
        title.setText("Java Weather Table");

        title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
        title.setGravity(Gravity.CENTER);
        title.setTypeface(Typeface.SERIF, Typeface.BOLD);

        TableRow.LayoutParams params = new TableRow.LayoutParams();
        params.span = 6;

        rowTitle.addView(title, params);

        // labels column
        TextView highsLabel = new TextView(this);
        highsLabel.setText("Day High");
        highsLabel.setTypeface(Typeface.DEFAULT_BOLD);

        TextView lowsLabel = new TextView(this);
        lowsLabel.setText("Day Low");
        lowsLabel.setTypeface(Typeface.DEFAULT_BOLD);

        TextView conditionsLabel = new TextView(this);
        conditionsLabel.setText("Conditions");
        conditionsLabel.setTypeface(Typeface.DEFAULT_BOLD);

        rowDayLabels.addView(empty);
        rowHighs.addView(highsLabel);
        rowLows.addView(lowsLabel);
        rowConditions.addView(conditionsLabel);

        // day 1 column
        TextView day1Label = new TextView(this);
        day1Label.setText("Feb 7");
        day1Label.setTypeface(Typeface.SERIF, Typeface.BOLD);

        TextView day1High = new TextView(this);
        day1High.setText("28°F");
        day1High.setGravity(Gravity.CENTER_HORIZONTAL);

        TextView day1Low = new TextView(this);
        day1Low.setText("15°F");
        day1Low.setGravity(Gravity.CENTER_HORIZONTAL);

        ImageView day1Conditions = new ImageView(this);
        day1Conditions.setImageResource(R.drawable.hot);

        rowDayLabels.addView(day1Label);
        rowHighs.addView(day1High);
        rowLows.addView(day1Low);
        rowConditions.addView(day1Conditions);

        // day2 column
        TextView day2Label = new TextView(this);
        day2Label.setText("Feb 8");
        day2Label.setTypeface(Typeface.SERIF, Typeface.BOLD);

        TextView day2High = new TextView(this);
        day2High.setText("26°F");
        day2High.setGravity(Gravity.CENTER_HORIZONTAL);

        TextView day2Low = new TextView(this);
        day2Low.setText("14°F");
        day2Low.setGravity(Gravity.CENTER_HORIZONTAL);

        ImageView day2Conditions = new ImageView(this);
        day2Conditions.setImageResource(R.drawable.pt_cloud);

        rowDayLabels.addView(day2Label);
        rowHighs.addView(day2High);
        rowLows.addView(day2Low);
        rowConditions.addView(day2Conditions);

        // day3 column
        TextView day3Label = new TextView(this);
        day3Label.setText("Feb 9");
        day3Label.setTypeface(Typeface.SERIF, Typeface.BOLD);

        TextView day3High = new TextView(this);
        day3High.setText("23°F");
        day3High.setGravity(Gravity.CENTER_HORIZONTAL);

        TextView day3Low = new TextView(this);
        day3Low.setText("3°F");
        day3Low.setGravity(Gravity.CENTER_HORIZONTAL);

        ImageView day3Conditions = new ImageView(this);
        day3Conditions.setImageResource(R.drawable.snow);

        rowDayLabels.addView(day3Label);
        rowHighs.addView(day3High);
        rowLows.addView(day3Low);
        rowConditions.addView(day3Conditions);

        // day4 column
        TextView day4Label = new TextView(this);
        day4Label.setText("Feb 10");
        day4Label.setTypeface(Typeface.SERIF, Typeface.BOLD);

        TextView day4High = new TextView(this);
        day4High.setText("17°F");
        day4High.setGravity(Gravity.CENTER_HORIZONTAL);

        TextView day4Low = new TextView(this);
        day4Low.setText("5°F");
        day4Low.setGravity(Gravity.CENTER_HORIZONTAL);

        ImageView day4Conditions = new ImageView(this);
        day4Conditions.setImageResource(R.drawable.lt_snow);

        rowDayLabels.addView(day4Label);
        rowHighs.addView(day4High);
        rowLows.addView(day4Low);
        rowConditions.addView(day4Conditions);

        // day5 column
        TextView day5Label = new TextView(this);
        day5Label.setText("Feb 11");
        day5Label.setTypeface(Typeface.SERIF, Typeface.BOLD);

        TextView day5High = new TextView(this);
        day5High.setText("19°F");
        day5High.setGravity(Gravity.CENTER_HORIZONTAL);

        TextView day5Low = new TextView(this);
        day5Low.setText("6°F");
        day5Low.setGravity(Gravity.CENTER_HORIZONTAL);

        ImageView day5Conditions = new ImageView(this);
        day5Conditions.setImageResource(R.drawable.pt_sun);

        rowDayLabels.addView(day5Label);
        rowHighs.addView(day5High);
        rowLows.addView(day5Low);
        rowConditions.addView(day5Conditions);

        table.addView(rowTitle);
        table.addView(rowDayLabels);
        table.addView(rowHighs);
        table.addView(rowLows);
        table.addView(rowConditions);

        setContentView(table);

    }

Усадка, усушка, утруска

Если текст в ячейке таблицы слишком длинный, то он может растянуть ячейку таким образом, что часть текста просто выйдет за пределы видимости. Чтобы избежать данной проблемы, у контейнтера TableLayout есть атрибут android:shrinkColumns. Мы рассмотрим программное применение данного атрибута через метод setColumnShrinkable().

Для начала смоделируем ситуацию и поместим в одну из ячеек очень длинный текст, который не поместится на экран:


<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
         <TableLayout
            android:id="@+id/tablelayout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <TableRow>
                <TextView
                    android:text="Щелкните на кнопке Усадка, чтобы увидеть, как длинный текст может уместиться в ячейке таблицы"
                    android:padding="3dip" />
            </TableRow>
        </TableLayout>
        <Button
            android:id="@+id/toggle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Усадка" />
    </LinearLayout>
</ScrollView>

Теперь напишем код для усадки текста:


public class TableActivity extends Activity {

    private boolean mShrink;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        
        final TableLayout table = (TableLayout) findViewById(R.id.tablelayout);
        Button button = (Button) findViewById(R.id.toggle);
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                mShrink = !mShrink;
                table.setColumnShrinkable(0, mShrink);
            }
        });
        mShrink = table.isColumnShrinkable(0);
    }
}

TableLayout

TableLayout

Книжная полка

Создадим подобие книжной полки. Нам понадобится изображение одной полки, которая послужит фоном и изображение книги (найдите сами).

Подготовим разметку.


<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

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

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:src="@drawable/cat_bottom" />

        <TableLayout
            android:id="@+id/tableLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </TableLayout>
    </LinearLayout>

</ScrollView>

Объявим две константы, которые отвечают за количество полок и количество книг на каждой полке.


package ru.alexanderklimov.test;

import android.app.Activity;

import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;

public class MainActivity extends Activity {

	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		int BOOKSHELF_ROWS = 5;
		int BOOKSHELF_COLUMNS = 5;

		TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);

		for (int i = 0; i < BOOKSHELF_ROWS; i++) {

			TableRow tableRow = new TableRow(this);
			tableRow.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
					LayoutParams.WRAP_CONTENT));
			tableRow.setBackgroundResource(R.drawable.shelf);

			for (int j = 0; j < BOOKSHELF_COLUMNS; j++) {
				ImageView imageView = new ImageView(this);
				imageView.setImageResource(R.drawable.book);

				tableRow.addView(imageView, j);
			}
			
			tableLayout.addView(tableRow, i);
		}
	}
}

Bookshelf

Откуда на верхней полке появился кот и как он туда забрался я не знаю. Вы уж сами разберитесь с ним.

Реклама