はじめに
こんな感じに、EditTextやbutton等を画面ごとに大きさを変えたい!
画面の比率で作成したい!![]()
考え方
画面ごとにlayoutを変えるということは,tablayoutによるFragmentごとに layout file を作成して,その layout file ごとにitem(今回はEditTextやButton)配置してやればいいと考えましたが,今回は違うやり方です.
今回はFragmentを呼び出す元である,mainのActivityにてこれらを実装します.
ここで、私が考えたメリットを2つ紹介します.
1つめ
1つめのメリットは,親のlayoutで固定できることですかね??![]()
(私の実装ではFragmentの中にListViewやRecyclerViewなどを実装したときにスクロールでitem(今回はEditTextやButton)が動いてしまいました.)
2つめ
2つめのメリットはFragmentのlayout file それぞれに記述しなくていいので,冗長にならない点??![]()
これは良いことだと思います.![]()
実装
tablayoutとviewpagerの連携
まずは,tablayoutとviewpagerを連携します.
今回はtabの数は5つとして,実装します.
そして,5つのFragmentとその中に入れる5つのlayout fileを用意します.
5つの layout file
<?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
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でくっつけます.
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にこれまで書いてきた文を処理させる
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 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 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で動的にする
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
多分これじゃない感がすごいですが,気になる点などありましたら意見バシバシよろしくお願いします.