はじめに
Android Studio 3.6.3 の Layout Editor の Palette に表示される UI コンポーネントについてまとめました。(結構多い。。。)
UI コンポーネントは大きく分けて TextView
などの View
と ConstraintLayout
のように複数の UI コンポーネントを中に配置する ViewGroup
がある。
Text
TextView
iOS でいう UILabel
相当だと思う。
定義
1 |
open class TextView : View, ViewTreeObserver.OnPreDrawListener |
参考:TextView
EditText
iOS でいう UITextField
, UITextView
相当だと思う。 プレースホルダーにあたるのは hint
。
定義
1 |
open class EditText : TextView |
inputType
の設定が色々ある。複数行表示の場合は textMultiLine
を設定する。
下記はすべて EditText
で inputType
が異なる値が設定されている。
- Plaint Text
- Password
- Password (Numeric)
- Phone
- Postal Address
- Multiline Text
- Time
- Date
- Number
- Number (Signed)
- Number (Decimal)
簡易実装(TextWatcher
で入力イベントを受け取れる)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
val editText = findViewById<EditText>(R.id.edit_text) editText.setText("Test", TextView.BufferType.NORMAL) // テキストを設定 val text = editText.text.toString() // テキストを取得 // 入力イベントの受信 editText.addTextChangedListener(object : TextWatcher { // 文字1つを入力した時に呼び出される override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { Log.d(TAG, "onTextChanged! ${s.toString()}, start: $start, before: $before, count: $count") } // 文字列が修正される直前に呼び出される override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { Log.d(TAG, "beforeTextChanged! ${s.toString()}, start: $start, count: $count, after: $after") } // 文字列が変更されたときに呼び出される。 override fun afterTextChanged(s: Editable) { Log.d(TAG, "afterTextChanged! ${s.toString()}") } }) |
"Tes" という状態で "t" を入力すると下記のようにログ出力された。
1 2 3 |
beforeTextChanged! Tes, start: 3, count: 0, after: 1 onTextChanged! Test, start: 3, before: 0, count: 1 afterTextChanged! Test |
参考:EditText
AutoCompleteTextView
自動補完機能を備えたテキストフィールド。ArrayAdapter
を実装してドロップダウンで入力候補を表示できる。
定義
1 |
open class AutoCompleteTextView : EditText, Filter.FilterListener |
MultiAutoCompleteTextView
AutoCompleteTextView
の拡張版。AutoCompleteTextView
との違いは、補完された文字列に ", " が付加され、単一テキストビュー内で連続して補完機能が使用できるらしい。
定義
1 |
open class MultiAutoCompleteTextView : AutoCompleteTextView |
TextInputLayout + TextInputEditText
マテリアルコンポーネントの1つ。入力するとプレースホルダーが上に移動する。
定義
1 2 3 |
public class TextInputLayout extends LinearLayout public class TextInputEditText extends AppCompatEditText |
参考
Buttons
ボタンはチェックボックスやラジオボタンなど標準で色々用意されている。CheckBox
などの OnCheckedChangeListener
は OnClickListener
より先に呼ばれる
Button
iOS でいう UIButton
に相当すると思う。
定義
1 |
open class Button : TextView |
デフォルトだとテキストがすべて大文字になるので小文字にしたい場合は textAllCaps
に false
を指定する。ハイライトなど細かい設定したい場合は style の XML を作成し、設定する。
下記の属性を組み合わせて使用すれば背景画像ありアイコンありテキストありのボタンも作成できる。
属性名 | 説明 |
---|---|
android:text | テキストを設定 |
android:drawableLeft | テキストの左に画像を設定 |
android:drawableTop | テキストの上に画像を設定 |
android:drawableRight | テキストの右に画像を設定 |
android:drawableBottom | テキストの下に画像を設定 |
android:drawableStart | テキストの先頭に画像を設定 |
android:drawableEnd | テキストの末尾に画像を設定 |
android:background | 背景に画像を設定 |
簡易実装
1 2 3 4 |
val button = findViewById<Button>(R.id.button) button.setOnClickListener { Log.d(TAG, "Button click!") } |
参考:Button
ImageButton
テキストがないボタン?タップできる ImageView
とでも思えばいいはず。。。
定義
1 |
open class ImageButton : ImageView |
簡易実装
1 2 3 4 |
val imageButton = findViewById<ImageButton>(R.id.image_button) imageButton.setOnClickListener { Log.d(TAG, "ImageButton click!") } |
参考:ImageButton
ChipGroup + Chip
マテリアルコンポーネントの1つ。ラジオボタンのようなはてブのタグのようなやつ。
定義
1 2 3 |
public class ChipGroup extends ViewGroup public class Chip extends AppCompatCheckBox implements ChipDrawable.Delegate, Shapeable |
これ入れないと InvocationTargetException になった。。。
1 |
android:theme="@style/Theme.MaterialComponents.Light" |
簡易実装
1 2 3 4 5 6 7 8 9 |
val chipGroup = findViewById<ChipGroup>(R.id.chip_group) chipGroup.check(R.id.chip2) val chipId = chipGroup.checkedChipId Log.d(TAG, "ChipGroup Selected! id: $chipId") // chipGroup.check(R.id.chip2) でも呼ばれる // Chip.Entryは呼ばれるけどChip.Actionは呼ばれないかも? chipGroup.setOnCheckedChangeListener { group, id -> Log.d(TAG, "ChipGroup CheckedChange! id: $id") } |
参考
CheckBox
標準でチェックボックスがあるのはすばらしい!
定義
1 |
open class CheckBox : CompoundButton |
簡易実装
1 2 3 4 5 6 7 8 9 |
val checkBox = findViewById<CheckBox>(R.id.check_box) checkBox.isChecked = true checkBox.setOnClickListener { Log.d(TAG, "CheckBox click!") } // heckBox.isChecked = true でも呼ばれる checkBox.setOnCheckedChangeListener { buttonView, isChecked -> Log.d(TAG, "CheckBox CheckedChange! isChecked: $isChecked") } |
参考:CheckBox
RadioGroup + RadioButton
標準でラジオボタンがあるのはすばらしい!RadioGroup
内に RadioButton
を置くことで一つのグループとして振る舞う。
定義
1 2 3 |
open class RadioGroup : LinearLayout open class RadioButton : CompoundButton |
簡易実装
1 2 3 4 5 6 7 8 |
val radioGroup = findViewById<RadioGroup>(R.id.radio_group) radioGroup.check(R.id.radio1) val id = radioGroup.checkedRadioButtonId Log.d(TAG, "RadioGroup Selected! id: $id") // radioGroup.check(R.id.radio1) でも呼ばれる radioGroup.setOnCheckedChangeListener { group, id -> Log.d(TAG, "RadioGroup CheckedChange! id: $id") } |
参考
ToggleButton
トグルボタン。スイッチとの使い分けはデザイナーに聞こう!
定義
1 |
open class ToggleButton : CompoundButton |
簡易実装
1 2 3 4 5 6 7 8 9 |
val toggleButton = findViewById<ToggleButton>(R.id.toggle_button) toggleButton.isChecked = true toggleButton.setOnClickListener { Log.d(TAG, "ToggleButton click!") } // toggleButton.isChecked = trueでも呼ばれる toggleButton.setOnCheckedChangeListener { buttonView, isChecked -> Log.d(TAG, "ToggleButton CheckedChange! isChecked: $isChecked") } |
参考:ToggleButton
Switch
iOS でいう UISwitch
に相当すると思う。テキストも設定できる。
定義
1 |
open class Switch : CompoundButton |
簡易実装
1 2 3 4 5 6 7 8 9 |
val switch = findViewById<Switch>(R.id.toggle_switch) switch.isChecked = true switch.setOnClickListener { Log.d(TAG, "Switch click!") } // switch.isChecked = trueでも呼ばれる switch.setOnCheckedChangeListener { buttonView, isChecked -> Log.d(TAG, "Switch CheckedChange! isChecked: $isChecked") } |
参考:Switch
FloatingActionButton
マテリアルコンポーネントの1つ。Gmail アプリの右下にあるやつ。テキストはない。
定義
1 2 |
public class FloatingActionButton extends ImageButton implements TintableBackgroundView, TintableImageSourceView, ExpandableTransformationWidget, Shapeable |
簡易実装
1 2 3 4 |
val fab = findViewById<FloatingActionButton>(R.id.fab) fab.setOnClickListener { Log.d(TAG, "FloatingActionButton click!") } |
Widgets
View
iOS でいう UIView
に相当すると思うが addSubView
はできない。(その場合は ViewGroup
を使う)
定義
1 |
open class View : Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource |
Divider は backgroud
に ?android:attr/listDivide
が設定された View
。用意してくれているので境界線引きたいときに使おう!
- Horizontal Divider
- Vertical Divider
Horizontal Divider は下記のようになっている。(Vertical は width が 1dp に設定されている)
1 2 3 4 |
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="?android:attr/listDivider" /> |
参考:View
ImageView
iOS でいう UIImageView
に相当すると思う。
定義
1 |
open class ImageView : View |
参考:ImageView
WebView
iOS でいう WKWebView
に相当すると思う。
定義
1 |
open class WebView : AbsoluteLayout, ViewTreeObserver.OnGlobalFocusChangeListener, ViewGroup.OnHierarchyChangeListener |
ウェブページを表示するにはマニフェストに下記のような記述が必要。それでもエラーになる場合は一度アプリをアンインストールすると表示されるかも知れない。
1 |
<uses-permission android:name="android.permission.INTERNET" /> |
簡易実装(Webページ表示)
1 2 |
val webView = findViewById<WebView>(R.id.web) webView.loadUrl("https://www.am10.blog/?p=85") |
その他、http のサイト表示は設定がいったり、window.open の場合に処理が必要だったり色々面倒な設定がいった気がする。(このあたりはまた別記事でまとめたい。。。)
参考
VideoView
動画再生用の View。簡単に動画再生ができてすばらしい!(たしか iOS は表示をカスタムしようと思うと AVPlayerLayer とか使わないといけなかった気がする)
定義
1 |
open class VideoView : SurfaceView, MediaController.MediaPlayerControl |
端末内やネット上のリソースフォルダの動画を再生できる。
例では res/raw/sample.mp4 を再生している。 (movは再生できなかった。。。)
MediaController
を設定することで再生ボタンとかを簡単に表示できる。
簡易実装
1 2 3 4 |
val videoView = findViewById<VideoView>(R.id.video) videoView.setMediaController(MediaController(this)) // 動画部分タップで再生ボタンとか表示する videoView.setVideoURI(Uri.parse("android.resource://" + packageName + "/" + R.raw.sample)) videoView.start() |
参考:VideoView
CalendarView
その名の通りカレンダー。標準であるのはすばらしい!日付は UNIX 時間 (Long
型) で扱われます。
* UNIX 時間は1970年1月1日午前0時0分0秒を基準とした形式的な経過秒数らしい(参考:Wikipedia UNIX 時間)
定義
1 |
open class CalendarView : FrameLayout |
簡易実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
val calendarView = findViewById<CalendarView>(R.id.calendar) // 一日前選択 val calendar = Calendar.getInstance() calendar.add(Calendar.DATE, -1) calendarView.date = calendar.timeInMillis // 1月後を上限に設定 calendar.add(Calendar.MONTH, 1) calendarView.maxDate = calendar.timeInMillis // 1月前を下限に設定 calendar.add(Calendar.MONTH, -2) calendarView.minDate = calendar.timeInMillis calendarView.setOnDateChangeListener { view, year, month, dayOfMonth -> Log.d(TAG, "year: $year, month: $month, dayOfMonth: $dayOfMonth") val calendar = Calendar.getInstance() calendar.timeInMillis = view.date // これはまだ選択前の日付 val beforeDate = calendar.time calendar.set(year, month, dayOfMonth) val selectedDate = calendar.time val format = "yyyy/MM/dd E HH:mm:ss" Log.d(TAG, DateFormat.format(format, beforeDate).toString()) Log.d(TAG, DateFormat.format(format, selectedDate).toString()) } |
参考:CalendarView
ProgressBar
iOS でいう UIProgressView
に相当すると思う。円形や棒状の表示ができる。
定義
1 |
open class ProgressBar : View |
ProgressBar (Horizontal) は style
に ?android:attr/progressBarStyleHorizontal
が設定されている
簡易実装
1 2 |
val progressBar = findViewById<ProgressBar>(R.id.progress) progressBar.progress = 10 // 値設定 |
参考:ProgressBar
SeekBar
iOS でいう UISlider
に相当すると思う。
定義
1 |
open class SeekBar : AbsSeekBar |
SeekBar (Discrete) は style
に @style/Widget.AppCompat.SeekBar.Discrete
が設定されている。単位ごとに動かせるやつ?
簡易実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
val seekBar = findViewById<SeekBar>(R.id.seek_bar) seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { // 変更時に呼ばれる(seekBar.progress = 20などコードで変更時はfromUserがfalse) override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { Log.d(TAG, "SeekBar onProgressChanged! progress: $progress, fromUser: $fromUser") } // ツマミがタッチされた時に呼ばれる override fun onStartTrackingTouch(seekBar: SeekBar) { Log.d(TAG, "SeekBar onStartTrackingTouch!") } // ツマミがリリースされた時に呼ばれる override fun onStopTrackingTouch(seekBar: SeekBar) { Log.d(TAG, "SeekBar onStopTrackingTouch!") } }) seekBar.progress = 20 |
参考:SeekBar
RatingBar
星の数で評価を表示するやつ。(こんなのまで標準であるのか!?)
定義
1 |
open class RatingBar : AbsSeekBar |
簡易実装
1 2 3 4 5 6 7 |
val ratingBar = findViewById<RatingBar>(R.id.rating_bar) ratingBar.numStars = 5 // 星の数 ratingBar.stepSize = 0.5F // ステップ数 ratingBar.rating = 1.5F ratingBar.setOnRatingBarChangeListener { ratingBar, rating, fromUser -> Log.d(TAG, "RatingBar change! rating: $rating, fromUser: $fromUser") } |
参考:RatingBar
SearchView
iOS でいう UISearchBar
に相当すると思う。
定義
1 |
open class SearchView : LinearLayout, CollapsibleActionView |
簡易実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
val searchView = findViewById<SearchView>(R.id.search) searchView.queryHint = "Sample Text" // プレースホルダー searchView.setQuery("AAA", false) // テキスト設定 trueならonQueryTextSubmitが呼ばれる Log.d(TAG, "SearchView query: ${searchView.query.toString()}") searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { // テキスト入力時に呼ばれる override fun onQueryTextChange(newText: String): Boolean { Log.d(TAG, "SearchView onQueryTextChange newText: $newText") return false // リスナーで処理する場合はtrue、SearchViewのデフォルトアクションならfalse } // submit時に呼ばれる override fun onQueryTextSubmit(query: String): Boolean { Log.d(TAG, "SearchView onQueryTextChange query: $query") return false // リスナーで処理する場合はtrue、SearchViewのデフォルトアクションならfalse } }) |
参考:SearchView
TextureView
たぶん描画したいときとかに使うやつ。(あんまわかってない。。。)
定義
1 |
open class TextureView : View |
参考:TextureView
SurfaceView
たぶん描画したいときとかに使うやつ。(あんまわかってない。。。)
定義
1 |
open class SurfaceView : View |
参考:SurfaceView
Layouts
View
を横並びや重ねたりして配置するためのやつ。Layout はまた別記事でまとめたい。。。(まとめました -> Layout)
ConstraintLayout
他の View
との相対位置で配置するやつ。RelativeLayout
と似たような機能だが今はこちらが主流らしい。
定義
1 |
public class ConstraintLayout extends ViewGroup |
Guideline
ConstraintLayout
と組み合わせて水平や垂直に View
を整列させたりするのに使うらしい。 (参考)
定義
1 |
public class Guideline extends View |
参考:Guideline
LinearLayout
iOS でいう UIStackView
のようなものだと思う。垂直方向や水平方向に並べて配置するやつ。
定義
1 |
open class LinearLayout : ViewGroup |
参考:LinearLayout
FrameLayout
1つの View
だけを配置するときに使う軽量なやつ。複数 View
の配置には向かないみたい。View
を重ねるときにも使える。
定義
1 |
open class FrameLayout : ViewGroup |
参考:FrameLayout
TableLayout
View
を格子状に配置するためのやつ。
定義
1 |
open class TableLayout : LinearLayout |
参考:TableLayout
TableRow
TableLayout
の1つ1つの行。TableLayout
の子 View
として使う。(リファレンスにも下記のようにある)
A layout that arranges its children horizontally. A TableRow should always be used as a child of a TableLayout. If a TableRow's parent is not a TableLayout, the TableRow will behave as an horizontal LinearLayout.
定義
1 |
open class TableRow : LinearLayout |
参考:TableRow
Space
その名の通り余白用の View
。リファレンスにも下記のように書いてある。
Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.
定義
1 |
class Space : View |
参考:Space
Containers
Containers | \<include>とか |
---|---|
Spinner
ドロップダウン表示するやつ。SpinnerAdapter
でリストやレイアウトを設定する。
定義
1 |
open class Spinner : AbsSpinner, DialogInterface.OnClickListener |
簡易実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
val spinnerItems = listOf("AAA", "BBB", "CCC", "DDD", "EEE") val spinner = findViewById<Spinner>(R.id.spinner) val adapter = ArrayAdapter(applicationContext, android.R.layout.simple_spinner_item, spinnerItems) // adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) // これ必要かわからない spinner.adapter = adapter spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{ // アイテムが選択された時 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { val spinnerParent = parent as Spinner val item = spinnerParent.selectedItem as String Log.d(TAG, "onItemSelected! item: $item, position: $position, id: $id") } // アイテムが選択されなかった override fun onNothingSelected(parent: AdapterView<*>?) { Log.d(TAG, "onNothingSelected!") } } |
参考:Spinner
RecyclerView
iOS でいう UICollectionView
に相当するやつだと思う。Adapter
と LayoutManager
で色々設定する。縦に並べたり横に並べたり格子状に並べたり ListView
よりも柔軟な配置ができる。たぶんよく使うやつなので別記事でまとめたい。。。
定義
1 |
open class RecyclerView : ViewGroup, ScrollingView, NestedScrollingChild2, NestedScrollingChild3 |
簡易実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Activity val recyclerView = findViewById<RecyclerView>(R.id.recycler) val adapter = RecyclerViewAdapter(this) { position, item -> Log.d(TAG, "ClickItem! position: $position, item: $item") } recyclerView.adapter = adapter recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) class RecyclerViewAdapter(context: Context, private val onItemClicked: (position: Int, item: String) -> Unit) : Adapter<RecyclerViewAdapter.RecyclerViewHolder>() { private val list = listOf("AAA", "BBB", "CCC", "DDD", "EEE") private val inflater = LayoutInflater.from(context) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder { val view = inflater.inflate(R.layout.recycler_row, parent, false) val viewHolder = RecyclerViewHolder(view) view.setOnClickListener { val position = viewHolder.adapterPosition val item = list[position] onItemClicked(position, item) } return viewHolder } override fun getItemCount() = list.size override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) { val item = list[position] holder.text.text = item } class RecyclerViewHolder(view: View) : ViewHolder(view) { val text = view.findViewById<TextView>(R.id.text) } } |
選択イベントとかは独自にリスナーを用意しないといけないらしい。。。(OnItemTouchListener
はあるけど position
とか取れないので扱いづらい)
参考:RecyclerView
ScrollView
iOS でいう UIScrollView
に相当するやつだと思う。縦にスクロールする。横スクロールは後述の HorizontalScrollView
を利用する。
定義
1 |
open class ScrollView : FrameLayout |
下記のように ScrollView の子 View に設定するだけでスクロールできるようになる!
1 2 3 4 5 6 7 8 9 |
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <View android:layout_width="match_parent" android:layout_height="2000dp"/> </ScrollView> |
ScrollView に複数の子 View を設定すると下記のようなエラーでクラッシュする。
1 |
ScrollView can host only one direct child |
ScrollView
は子 View を一つしか持てないので複数の View を置きたい場合は LinearLayout を子 View に設定して LinearLayout の子に複数の View を設定する。ScrollView
は子 View に ScrollView
を使いたい場合は後述の NestedScrollView
を使う。
参考:ScrollView
HorizontalScrollView
横にスクロールする ScrollView
。
定義
1 |
open class HorizontalScrollView : FrameLayout |
NestedScrollView
その名の通り ScrollView
をネストするための ScrollView
。通常の ScrollView
は入れ子にするとイベントが親の ScrollView
に取られて子の ScrollView
をスクロールできない。
定義
1 2 |
public class NestedScrollView extends FrameLayout implements NestedScrollingParent, NestedScrollingChild2, ScrollingView |
RecyclerView
などの ScrollView
を NestedScrollView
配下に置く場合は下記のように設定するらしい(参考)
1 |
ViewCompat.setNestedScrollingEnabled(recyclerView, false) |
ViewPager
iOS でいう UIPageViewController
に相当すると思う。FragmentStatePagerAdapter
を設定してページごとに Fragment
を表示する。左右のスワイプでページが切り替わる。(縦にはできないみたい)
定義
1 |
open class ViewPager : ViewGroup |
簡易実装(色のついた3つのフラグメントを表示)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
class SampleFragmentPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getCount() = 3 override fun getItem(position: Int) = when (position) { 0 -> SampleFragment.newInstance(R.color.colorPrimary, "Sample Page 1") 1 -> SampleFragment.newInstance(R.color.colorAccent, "Sample Page 2") 2 -> SampleFragment.newInstance(R.color.colorPrimaryDark, "Sample Page 3") else -> SampleFragment.newInstance(R.color.colorPrimary, "Sample Page 1") } } class SampleFragment : Fragment() { private var resId: Int? = null private var sampleText: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { resId = it.getInt(ARG_RES_ID) sampleText = it.getString(ARG_SAMPLE_TEXT) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment val view = inflater.inflate(R.layout.fragment_sample, container, false) if (resId != null) { val layout = view.findViewById<FrameLayout>(R.id.main_layout) layout.setBackgroundResource(resId!!) } if (sampleText != null) { val text = view.findViewById<TextView>(R.id.sample_text) text.text = sampleText } return view } companion object { @JvmStatic fun newInstance(@ColorRes resId: Int, sampleText: String) = SampleFragment().apply { arguments = Bundle().apply { putInt(ARG_RES_ID, resId) putString(ARG_SAMPLE_TEXT, sampleText) } } } } class ViewPagerActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_view_pager) val viewPager = findViewById<ViewPager>(R.id.pager) val adapter = SampleFragmentPagerAdapter(supportFragmentManager) viewPager.adapter = adapter } } |
CardView
マテリアルコンポーネントの1つ。カードを表示する。
定義
1 |
open class CardView : FrameLayout |
参考:CardView
AppBarLayout
鋭意作成中。。。
定義
1 |
public class AppBarLayout extends LinearLayout |
参考:AppBarLayout
BottomAppBar
鋭意作成中。。。
定義
1 |
public class BottomAppBar extends Toolbar implements CoordinatorLayout.AttachedBehavior |
参考:BottomAppBar
NavigationView
左端から右にスワイプすると表示されるドロワー(詳細はこっち)
定義
1 |
public class NavigationView extends FrameLayout |
BottomNavigationView
画面下のタブバー(詳細はこっち)
定義
1 |
public class BottomNavigationView extends FrameLayout |
Toolbar
鋭意作成中。。。
定義
1 |
open class Toolbar : ViewGroup |
参考:Toolbar
TabLayout + TabItem
タブ。基本的には ViewPager
と組み合わせて使うっぽい。
定義
1 2 3 |
public class TabLayout extends HorizontalScrollView public class TabItem extends View |
TabItem
には text
と icon
が設定できる。ViewPager
を設定すると Adapter
の getPageTitle(position: Int): CharSequence?
の値が text
に設定される。
簡易実装(SampleFragmentPagerAdapter
は ViewPager
で使用したのと同様のやつです)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
val viewPager = findViewById<ViewPager>(R.id.pager) val adapter = SampleFragmentPagerAdapter(supportFragmentManager) viewPager.adapter = adapter val tabLayout = findViewById<TabLayout>(R.id.tab) tabLayout.setupWithViewPager(viewPager) // Pagerセット後なら独自のテキスト・アイコンを設定可能(セット前だとPagerのtitleになる) tabLayout.getTabAt(0)?.let { it.text = "TabA" } tabLayout.getTabAt(1)?.let { it.text = "" it.setIcon(R.drawable.botman_black) } tabLayout.getTabAt(2)?.let { it.text = "TabC" it.setIcon(R.drawable.botman_red) } |
参考
ViewStub
仮置の View
。たぶん重たい View
を読み込むときに使うやつ。 inflate()
するまで読み込まれないのでたぶん軽くなる。
定義
1 |
class ViewStub : View |
下記のように読み込む View
は XML 上でもコードでも設定できる。
1 2 3 4 5 |
<ViewStub android:id="@+id/stub" android:inflatedId="@+id/inflated" <!-- inflate後にViewStubと置き換えられるViewのID --> android:layout="@layout/inflate_layout" <!-- inflate後にViewStubと置き換えられるViewのlayout --> /> |
1 2 3 4 5 6 7 8 9 10 11 |
val viewStub = findViewById<ViewStub>(R.id.view_stub) // パターン1:xmlで指定したlayoutに置き換えられる viewStub.inflate() // パターン2:これでも可 viewStub.visibility = View.VISIBLE // パターン3:切り替えるlayoutを指定して切り替える viewStub.layoutResource = R.layout.inflate_layout viewStub.inflate() |
参考
\<include>
layout ファイルの中に他の layout ファイルのタグを挿入するタグ。
下記のように layout
に読み込む layout ファイルを指定する。(下記は MainActivity の layout を読み込んでいる)
1 2 3 4 |
<include layout="@layout/activity_main" android:layout_width="match_parent" android:layout_height="wrap_content" /> |
参考:\<include>
\<fragment>
layout ファイルの中に Fragment
のタグを挿入するタグ。
下記のように name
に読み込む Fragment
を指定する。
1 2 3 4 |
<fragment android:name="com.example.widgetsample.SampleFragment" android:layout_width="match_parent" android:layout_height="wrap_content" /> |
NavHostFragment
Navigation
を利用する時のコンテナ。たぶん UINavigationController
のようなやつ(詳細はこっち)
定義
1 |
open class NavHostFragment : Fragment, NavHost |
\<view>
指定の View
を挿入するタグ。(よくわかってない。。。)
試しに ViewPager
を挿入すると下記のようになった。
1 2 3 4 5 |
<view android:id="@+id/view" class="androidx.viewpager.widget.ViewPager" android:layout_width="match_parent" android:layout_height="wrap_content" /> |
\<requestFocus>
画面表示時に指定の View
にフォーカスするよう指定するタグ。
下記のようにすると EditText
にフォーカスされた。
1 2 3 4 5 6 |
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="Sample Text"> <requestFocus/> </EditText> |
Google API を利用するやつ。別途 API キーの生成等必要。
AdView
広告表示をするやつ。
定義
1 |
public final class AdView extends ViewGroup |
参考:AdView
MapView
iOS でいう MKMapView に相当すると思う。 API キーの生成が必要。
定義
1 |
public class MapView extends FrameLayout |
参考:MapView
Legacy
GridLayout
格子状に View
を配置するやつ。TableLayout
と同じ感じがするがこっちは列をまたいで配置できるらしい。(Layout の記事でまとめたい。。。(まとめました -> Layout))
定義
1 |
open class GridLayout : ViewGroup |
ListView
iOS でいう UITableView
に相当すると思う。Adapter
で色々設定する。UITableView
でいう DataSource が Adapter
、Delegate が Listener
だと思う。よく使うやつなので別記事でまとめたい。。。
定義
1 |
open class ListView : AbsListView |
簡易実装(テキスト表示するだけとか単純なやつなら android.R に layout 用意されている)
1 2 3 4 5 6 7 8 |
val listView = findViewById<ListView>(R.id.list) val list = listOf("AAA", "BBB", "CCC") val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, list) listView.adapter = adapter listView.setOnItemClickListener { parent, view, position, id -> // 行タップ時の処理 val text = adapter.getItem(position) } |
参考:ListView
TabHost
タブ付きのコンテナらしいけど下記のように deprecated になっていて変わりに TabLayout
と ViewPager
を使えとあるので割愛。
This class was deprecated in API level R.
new applications should use fragment APIs instead of this class: Use TabLayout and ViewPager instead.
定義
1 |
open class TabHost : FrameLayout, ViewTreeObserver.OnTouchModeChangeListener |
参考:TabHost
RelativeLayout
他の View
との相対位置で配置するやつ。ConstraintLayout
と似たような機能だが今は ConstraintLayout
が主流らしい。
定義
1 |
open class RelativeLayout : ViewGroup |
GridView
格子状に配置するやつ。アイテム選択イベントも取れるので UICollectionView
に近いかも?
定義
1 |
open class GridView : AbsListView |
下記のように余白や列数を指定できる。
1 2 3 4 |
android:horizontalSpacing="8dp" android:verticalSpacing="8dp" android:numColumns="2" android:stretchMode="columnWidth" |
android:stretchMode
- columnWidth: 各列が同じ幅にストレッチされる
- none: ストレッチ無し
- spacingWidth: spacingで指定した値と余る余白を均等に分けた幅を加算
- spacingWidthUniform: 画像の解像度やその他の設定に応じて配置、余白がでる
簡易実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// Activity val gridView = findViewById<GridView>(R.id.grid) val adapter = GridViewAdapter(this, listOf(R.drawable.botman_red, R.drawable.botman_blue, R.drawable.botman_green, R.drawable.botman_yellow, R.drawable.botman_pink, R.drawable.botman_black, R.drawable.botman_orange, R.drawable.botman_purple)) gridView.adapter = adapter gridView.setOnItemClickListener { _, _, position, id -> Log.d(TAG, "Click! position: $position, id: $id") } class GridViewAdapter(private val context: Context, private val imageList: List<Int>) : BaseAdapter() { private val inflater = LayoutInflater.from(context) override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val view = convertView ?: createView(parent) val item = getItem(position) val viewHolder = view.tag as ViewHolder viewHolder.image.setImageResource(item) return view } override fun getItem(position: Int) = imageList[position] override fun getItemId(position: Int) = position.toLong() override fun getCount() = imageList.size private fun createView(parent: ViewGroup?): View { val view = inflater.inflate(R.layout.grid_item, parent, false) view.tag = ViewHolder(view) return view } private class ViewHolder(view: View) { val image = view.findViewById<ImageView>(R.id.image) } } |
参考
さいごに
あまりに時間がかかるので途中で投稿!!残りも随時作成予定。。。
コメント