1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-06-11

はじめに

device.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

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

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でくっつけます.

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にこれまで書いてきた文を処理させる

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の連携
}
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宣言

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で動的にする

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
多分これじゃない感がすごいですが,気になる点などありましたら意見バシバシよろしくお願いします.

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?