画面に配置するButtonとEditTextをページごとに大きさ変えたり隠したり

# はじめに
<img width="300dp" alt="device.gif" src="https://qiita-image-store.s3.amazonaws.com/0/129578/fe8d3759-bb8e-2d60-17a8-8011790fa4ec.gif">

こんな感じに、EditTextやbutton等を画面ごとに大きさを変えたい！
画面の比率で作成したい！:clap_tone2:

# 考え方
画面ごとにlayoutを変えるということは，tablayoutによるFragmentごとに layout file を作成して，その layout file ごとにitem(今回はEditTextやButton)配置してやればいいと考えましたが，今回は違うやり方です．
今回はFragmentを呼び出す元である，mainのActivityにてこれらを実装します．
ここで、私が考えたメリットを2つ紹介します．
### 1つめ
1つめのメリットは，親のlayoutで固定できることですかね？？:point_up:
(私の実装ではFragmentの中にListViewやRecyclerViewなどを実装したときにスクロールでitem(今回はEditTextやButton)が動いてしまいました．)

### 2つめ
2つめのメリットはFragmentのlayout file それぞれに記述しなくていいので，冗長にならない点？？:clap_tone2:
これは良いことだと思います．:sunny:

# 実装

## tablayoutとviewpagerの連携

まずは，tablayoutとviewpagerを連携します．
今回はtabの数は5つとして，実装します．
そして，5つのFragmentとその中に入れる5つのlayout fileを用意します．

### 5つの layout file

```xml:layout/layout1.xml
<?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:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView1" />
</LinearLayout>
```
layout/layout1.xml
layout/layout2.xml
layout/layout3.xml
layout/layout4.xml
layout/layout5.xml
こんなかんじで，layout fileを5つ用意してください．

### 5つのFragment file

```java:Fragment1.java
package jp.app.oomae.hisaki.dynamic_button_sample.Fragment;

import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import jp.app.oomae.hisaki.dynamic_button_sample.R;

public class Fragment1 extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
        View view = inflater.inflate(R.layout.layout1, container, false);//R.layout.layout1～5に変えてください
        return view;
    }
}
```
Fragment1.java
Fragment2.java
Fragment3.java
Fragment4.java
Fragment5.java
こんなかんじで，5つ用意してください．

### adapter

tablayoutと5つのFragmentをadapterでくっつけます．

```java:Viewpager_Adapter.java
package jp.app.oomae.hisaki.dynamic_button_sample;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import jp.app.oomae.hisaki.dynamic_button_sample.Fragment.Fragment1;
import jp.app.oomae.hisaki.dynamic_button_sample.Fragment.Fragment2;
import jp.app.oomae.hisaki.dynamic_button_sample.Fragment.Fragment3;
import jp.app.oomae.hisaki.dynamic_button_sample.Fragment.Fragment4;
import jp.app.oomae.hisaki.dynamic_button_sample.Fragment.Fragment5;

public class Viewpager_Adapter extends FragmentPagerAdapter {
    int numberOfTabs;

    private String tabTitles[];

    public Viewpager_Adapter(FragmentManager fm, String[] tabTitles){
        super(fm);
        this.tabTitles = tabTitles;
        numberOfTabs = tabTitles.length;
    }

    @Override public Fragment getItem(int position) {
        switch (position){
            case 0:
                return new Fragment1();
            case 1:
                return new Fragment2();
            case 2:
                return new Fragment3();
            case 3:
                return new Fragment4();
            case 4:
                return new Fragment5();
        }
        return null;
    }
    @Override public int getCount() {
        return numberOfTabs;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }
}
```

### mainにこれまで書いてきた文を処理させる

```java:MainActivity.java
package jp.app.oomae.hisaki.dynamic_button_sample;



import android.os.Build;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    private ViewPager mPager;
    private TabLayout tabLayout;
    private Viewpager_Adapter pagerAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] tabs_names = getResources().getStringArray(R.array.tabs);//xmlファイルから配列取得
        tabLayout = (TabLayout) findViewById(R.id.tabs);//tablayoutのid取得
        mPager = (ViewPager) findViewById(R.id.viewpager);//viewpagerのid取得
        pagerAdapter = new Viewpager_Adapter(getSupportFragmentManager(), tabs_names);//作成したfragmentとviewpagerのadapterを作成
        mPager.setAdapter(pagerAdapter);//viewpagerにfragmentをセット
        mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));//tablayoutでも移動できるようにする
        tabLayout.setupWithViewPager(mPager);//tablayoutとviewpagerの連携
}
```

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="jp.app.oomae.hisaki.dynamic_button_sample.MainActivity">
    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
```

これで下地はできましたので，今回の目的であるlayoutのitemを動的に変更したいと思います．

# 本題

## 動的にするButtonとEditText宣言
```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="jp.app.oomae.hisaki.dynamic_button_sample.MainActivity">
    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
<!------------------------ここから追加------------------------------->
    <LinearLayout
        android:layout_gravity="bottom"
        android:id="@+id/linear"
        android:gravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:id="@+id/edittext1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:gravity="center"
            android:hint="コメントする" />
        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:text="送信" />
    </LinearLayout>
<!------------------------ここまで---------------------------------->
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
```
ポイントはdefaltのwidthとheightが0dpになっています．最初から，表示させないためです．
最初から表示させたい場合は，ここの0dpを任意の値にします．

## MainActivityで動的にする

```java:MainActivity.java
package jp.app.oomae.hisaki.dynamic_button_sample;



import android.os.Build;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    private ViewPager mPager;
    private TabLayout tabLayout;
    private Viewpager_Adapter pagerAdapter;
    private LinearLayout linearLayout;
    private int linear_width;
    private EditText editText;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      
        String[] tabs_names = getResources().getStringArray(R.array.tabs);//xmlファイルから配列取得
        tabLayout = (TabLayout) findViewById(R.id.tabs);//tablayoutのid取得
        mPager = (ViewPager) findViewById(R.id.viewpager);//viewpagerのid取得
        pagerAdapter = new Viewpager_Adapter(getSupportFragmentManager(), tabs_names);//作成したfragmentとviewpagerのadapterを作成
        mPager.setAdapter(pagerAdapter);//viewpagerにfragmentをセット
        mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));//tablayoutでも移動できるようにする
        tabLayout.setupWithViewPager(mPager);//tablayoutとviewpagerの連携
/*-------------------------------------ここから追加-----------------------------------------------------*/
        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {//ページ切り替えが来た時に入る
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {//ページがposition番号になったときに起動
                button = (Button)findViewById(R.id.button1);//id取得
                editText = (EditText)findViewById(R.id.edittext1);//id取得
                if (position == 0) {
                    editText.setLayoutParams(new LinearLayout.LayoutParams(0,0));//縦横設定
                    button.setLayoutParams(new LinearLayout.LayoutParams(0,0));//縦横設定
                } else if (position == 1) {
                    editText.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*0),getActionBarHeight()));//縦横設定
                    button.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*10),getActionBarHeight()));//縦横設定
                } else if (position == 2){
                    editText.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*5),getActionBarHeight()));//縦横設定
                    button.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*5),getActionBarHeight()));//縦横設定
                } else if (position == 3){
                    editText.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*8),getActionBarHeight()));//縦横設定
                    button.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*2),getActionBarHeight()));//縦横設定
                } else if (position == 4){
                    editText.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*10),getActionBarHeight()));//縦横設定
                    button.setLayoutParams(new LinearLayout.LayoutParams((int)((linear_width/10)*0),getActionBarHeight()));//縦横設定
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }

        });
    }

    @Override//LinearLayoutの大きさを取得する(※onCreateではできない)
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        linearLayout = (LinearLayout)findViewById(R.id.linear);
        linear_width = linearLayout.getWidth();
    }

    private int getActionBarHeight() {//固定値を取得(今回はactionbarのデフォルトの高さを取得して返します)
        int actionBarHeight = getSupportActionBar().getHeight();
        if (actionBarHeight != 0)
            return actionBarHeight;
        final TypedValue tv = new TypedValue();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
                actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
        } else if (getTheme().resolveAttribute(jp.app.oomae.hisaki.dynamic_button_sample.R.attr.actionBarSize, tv, true))
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
        return actionBarHeight;
    }

/*---------------------------------------------------ここまで----------------------------------------------*/
}
```

ページ番号が変わったときに，取得していた画面の横の長さを取得し，10分割し，その中でEditTextに7割り当て，Buttonに3割り当て，という風に実装しています．
そして0を代入すると，ButtonやEditText自体が消えます．

# 参考文献
viewpagerとFragmentとTablayout
http://notebook-t-0731.hatenablog.com/entry/2015/12/20/ViewPager%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8BActivity%E3%81%AEToolbar%E3%81%AE%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%92Fragment%E3%81%94%E3%81%A8%E3%81%AB%E5%A4%89%E6%9B%B4
画面サイズ取得
http://qiita.com/a_nishimura/items/f557138b2d67b9e1877c
http://tokin-kame.hatenablog.com/entry/2015/03/25/203907
ButtonやEditTextの大きさをセットする
https://stackoverflow.com/questions/20964597/how-to-set-height-and-width-of-the-dynamic-button-created
https://stackoverflow.com/questions/12301510/how-to-get-the-actionbar-height

# まとめ
今回のコードです．
https://github.com/hisakioomae/Dynamic_Button_size_sample
多分これじゃない感がすごいですが，気になる点などありましたら意見バシバシよろしくお願いします．