SQLの窓

2016年08月01日


Android : TabHost 内の各 TabSpec 内にある TextView の 端末回転時における保存と復帰

TabHost そのものは、ひとつの Activity で処理する場合とても簡単ですが、Android Studio の デザインで各タブの画面を確認できるように、xml で3つの画面定義をして activity_main.xml で include で読み込んでいます。

include タグにはそれぞれ id を設定して、TabSpec のコンテンツとして渡せるようにもしてあります。

端末回転時の保存と復帰に関しても、一般的な onSaveInstanceState と onRestoreInstanceState を使用していますが、画面内のコンテンツの id のパターンを以下のようにして、サンプルコードを作成しています。

1) EditText と Button には全て違った id を設定する
2) TextView には同じ id を設定する

通常、EditText は内部で自動的に内容が保存されて復帰されますが、3つの inclide 内の id を同じにしてしまうと( つまり、ひとつの画面定義で3つの include を使いまわししてしまうと )、保存と復帰がうまくいかないようなので、3つの画面を作成して、別々の id を設定しています。

しかし、同じ id を持った画面を使いまわす事も想定して、TextView には同じ id を設定して、include の id でまず view を取得して、その中の TextView として取得するサンプルコードです。


ここでは、使用していませんが最近の Drawable の取得方法として
Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.□□□, null);

そして、Tab にアイコンを表示させる方法について
Icon in Tab is not showing up (StackOverflow)
※ 要するにカスタムなインジケータを作成するそうです
public class MainActivity extends AppCompatActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// TabHost のインスタンスを取得
		TabHost tabhost = (TabHost)MainActivity.this.findViewById(R.id.tabHost);
		// タブ追加の前に必要な初期処理
		tabhost.setup();

		// タブ用のインスタンスを作成
		TabHost.TabSpec tab1 = tabhost.newTabSpec("tab1");
		// タイトル文字列を設定
		tab1.setIndicator("タブ1の\nタイトル");
		// このタブ内に表示するコンテンツを TabHost 画面内の FrameLayout
		// の中にあるうちのコンテンツのひとつを設定
		tab1.setContent(R.id.linearLayout1);
		// TabHost に このタブを追加
		tabhost.addTab(tab1);

		TabHost.TabSpec tab2 = tabhost.newTabSpec("tab2");
		tab2.setIndicator("タブ2の\nタイトル");
		tab2.setContent(R.id.linearLayout2);
		tabhost.addTab(tab2);

		TabHost.TabSpec tab3 = tabhost.newTabSpec("tab3");
		tab3.setIndicator("タブ3の\nタイトル");
		tab3.setContent(R.id.linearLayout3);
		tabhost.addTab(tab3);

		// tab1 内のボタン
		Button button1;
		button1 = (Button) MainActivity.this.findViewById(R.id.button);
		button1.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				TextView tv;
				// 画面最上部の TextView
				tv = (TextView) MainActivity.this.findViewById(R.id.textView);

				// 最初のタブの EditText
				EditText editText = (EditText) MainActivity.this.findViewById(R.id.editText);
				tv.setText(editText.getText().toString());

				// tab1 のコンテンツを取得
				View tab1 = MainActivity.this.findViewById(R.id.linearLayout1);
				tv = (TextView) tab1.findViewById(R.id.textView2);
				tv.setText(editText.getText().toString());

			}
		});

		// tab2 内のボタン
		Button button2;
		button2 = (Button) MainActivity.this.findViewById(R.id.button2);
		button2.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				TextView tv;

				// 真ん中のタブの EditText
				EditText editText = (EditText) MainActivity.this.findViewById(R.id.editText2);

				// tab2 のコンテンツを取得
				View tab2 = MainActivity.this.findViewById(R.id.linearLayout2);
				tv = (TextView) tab2.findViewById(R.id.textView2);
				tv.setText(editText.getText().toString());

			}
		});


	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);

		TabHost tabhost = (TabHost)findViewById(R.id.tabHost);

		// タブ位置の復帰
		int currentTab =  savedInstanceState.getInt("CurrentTab");
		if ( currentTab != 0l ) {
			tabhost.setCurrentTab(currentTab);
		}
		else {
			tabhost.setCurrentTab(0);
		}

		// 一番上の TextView を復帰
		String textTop = savedInstanceState.getString("TextViewTop");
		if (textTop != null ) {
			TextView tv;
			tv = (TextView) MainActivity.this.findViewById(R.id.textView);
			tv.setText(textTop);
		}

		// tab1 内の TextView を復帰
		String text1 = savedInstanceState.getString("TextView1");
		if (text1 != null ) {
			View tab1 = MainActivity.this.findViewById(R.id.linearLayout1);
			TextView tv = (TextView) tab1.findViewById(R.id.textView2);
			tv.setText(text1);
		}

		// tab2 内の TextView を復帰
		String text2 = savedInstanceState.getString("TextView2");
		if (text2 != null ) {
			View tab2 = MainActivity.this.findViewById(R.id.linearLayout2);
			TextView tv = (TextView) tab2.findViewById(R.id.textView2);
			tv.setText(text2);
		}

	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		// タブ位置の保存
		TabHost tabhost = (TabHost)MainActivity.this.findViewById(R.id.tabHost);
		int currentTab = tabhost.getCurrentTab();
		outState.putInt("CurrentTab", currentTab);

		// 一番上の TextView を保存
		TextView tvTop = (TextView) MainActivity.this.findViewById(R.id.textView);
		outState.putString("TextViewTop", tvTop.getText().toString());

		// tab1 のコンテンツを取得
		View tab1 = MainActivity.this.findViewById(R.id.linearLayout1);
		TextView tv1 = (TextView) tab1.findViewById(R.id.textView2);
		outState.putString("TextView1", tv1.getText().toString());

		// tab2 のコンテンツを取得
		View tab2 = MainActivity.this.findViewById(R.id.linearLayout2);
		TextView tv2 = (TextView) tab2.findViewById(R.id.textView2);
		outState.putString("TextView2", tv2.getText().toString());

	}
}


画面定義
<?xml version="1.0" encoding="utf-8"?>
<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="lightbox.july.tabhostapplication.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:textSize="30dp"/>

    <TabHost
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/tabHost"
        android:layout_below="@+id/textView">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
            </TabWidget>

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <include
                    android:id="@+id/linearLayout1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/tab_entry"/>

                <include
                    android:id="@+id/linearLayout2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/tab_entry2"/>

                <include
                    android:id="@+id/linearLayout3"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/tab_entry3"/>

            </FrameLayout>
        </LinearLayout>
    </TabHost>
</RelativeLayout>


3つの tab 毎の定義
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/textView2"
        android:textSize="40dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="入力を表示"
        android:id="@+id/button"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText"/>

</LinearLayout>

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/textView2"
        android:textSize="40dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="入力を表示"
        android:id="@+id/button2"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText2"/>

</LinearLayout>

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/textView2"
        android:textSize="40dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="なにもしない"
        android:id="@+id/button3"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText3"/>

</LinearLayout>
※ 便宜上3つにまとめていますが、xml ファイルはそれぞれ 作成しています



【Android Studio 2の最新記事】
posted by lightbox at 2016-08-01 13:40 | Android Studio 2 | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり