ดูไฟล์ต่างๆเมื่อสร้างโปรเจ็กส์ใหม่แบบ Tabbed Activity
- AndroidManifest.xml
- build.gradle (Project: MyApplication)
- build.gradle (Module: app)
- activity_main.xml
- fragment_main.xml
- values/dimens.xml
- values-w820dp/dimens.xml
- values/strings.xml
- values/styles.xml
- MainActivity.kt
- ui.main.PageViewModel.kt
- ui.main.PlaceholderFragment.kt
- ui.main.SectionsPagerAdapter.kt
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution" package="com.phaisarn.myapplication"> <dist:module dist:instant="true"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
build.gradle (Project: MyApplication)
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = '1.3.31' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
build.gradle (Module: app)
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 buildToolsVersion "29.0.0" defaultConfig { applicationId "com.phaisarn.myapplication" minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.2' implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minHeight="?actionBarSize" android:padding="@dimen/appbar_padding" android:text="@string/app_name" android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"/> <com.google.android.material.tabs.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary"/> </com.google.android.material.appbar.AppBarLayout> <androidx.viewpager.widget.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" app:srcCompat="@android:drawable/ic_dialog_email"/> </androidx.coordinatorlayout.widget.CoordinatorLayout>
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.main.PlaceholderFragment"> <TextView android:id="@+id/section_label" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:layout_constraintTop_creator="1" android:layout_marginStart="@dimen/activity_horizontal_margin" android:layout_marginEnd="@dimen/activity_horizontal_margin" android:layout_marginTop="@dimen/activity_vertical_margin" android:layout_marginBottom="@dimen/activity_vertical_margin" tools:layout_constraintLeft_creator="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="@+id/constraintLayout"/> </androidx.constraintlayout.widget.ConstraintLayout>
values/dimens.xml
<resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="appbar_padding">16dp</dimen> <dimen name="fab_margin">16dp</dimen> <dimen name="appbar_padding_top">8dp</dimen> </resources>
values-w820dp/dimens.xml
<resources> <!-- Example customization of dimensions originally defined in res/values/dimens.xml (such as screen margins) for screens with more than 820dp of available width. This would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> <dimen name="activity_horizontal_margin">64dp</dimen> </resources>
values/strings.xml
<resources> <string name="app_name">My Application</string> <string name="tab_text_1">Tab 1</string> <string name="tab_text_2">Tab 2</string> </resources>
values/styles.xml
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="AppTheme.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> </resources>
MainActivity.kt
package com.phaisarn.myapplication import android.os.Bundle import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayout import androidx.viewpager.widget.ViewPager import androidx.appcompat.app.AppCompatActivity import android.view.Menu import android.view.MenuItem import com.phaisarn.myapplication.ui.main.SectionsPagerAdapter class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager) val viewPager: ViewPager = findViewById(R.id.view_pager) viewPager.adapter = sectionsPagerAdapter val tabs: TabLayout = findViewById(R.id.tabs) tabs.setupWithViewPager(viewPager) val fab: FloatingActionButton = findViewById(R.id.fab) fab.setOnClickListener { view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show() } } }
ui.main.PageViewModel.kt
package com.phaisarn.myapplication.ui.main import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider class PageViewModel : ViewModel() { private val _index = MutableLiveData<Int>() val text: LiveData<String> = Transformations.map(_index) { "Hello world from section: $it" } fun setIndex(index: Int) { _index.value = index } }
ui.main.PlaceholderFragment.kt
package com.phaisarn.myapplication.ui.main import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.phaisarn.myapplication.R /** * A placeholder fragment containing a simple view. */ class PlaceholderFragment : Fragment() { private lateinit var pageViewModel: PageViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) pageViewModel = ViewModelProviders.of(this).get(PageViewModel::class.java).apply { setIndex(arguments?.getInt(ARG_SECTION_NUMBER) ?: 1) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val root = inflater.inflate(R.layout.fragment_main, container, false) val textView: TextView = root.findViewById(R.id.section_label) pageViewModel.text.observe(this, Observer<String> { textView.text = it }) return root } companion object { /** * The fragment argument representing the section number for this * fragment. */ private const val ARG_SECTION_NUMBER = "section_number" /** * Returns a new instance of this fragment for the given section * number. */ @JvmStatic fun newInstance(sectionNumber: Int): PlaceholderFragment { return PlaceholderFragment().apply { arguments = Bundle().apply { putInt(ARG_SECTION_NUMBER, sectionNumber) } } } } }
ui.main.SectionsPagerAdapter.kt
package com.phaisarn.myapplication.ui.main import android.content.Context import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentPagerAdapter import com.phaisarn.myapplication.R private val TAB_TITLES = arrayOf( R.string.tab_text_1, R.string.tab_text_2 ) /** * A [FragmentPagerAdapter] that returns a fragment corresponding to * one of the sections/tabs/pages. */ class SectionsPagerAdapter(private val context: Context, fm: FragmentManager) : FragmentPagerAdapter(fm) { override fun getItem(position: Int): Fragment { // getItem is called to instantiate the fragment for the given page. // Return a PlaceholderFragment (defined as a static inner class below). return PlaceholderFragment.newInstance(position + 1) } override fun getPageTitle(position: Int): CharSequence? { return context.resources.getString(TAB_TITLES[position]) } override fun getCount(): Int { // Show 2 total pages. return 2 } }