前提・実現したいこと
Androidアプリ開発で、最初のプロジェクト選択でBottom Navigation Activityを選び、デフォルトの「home・dashboard・notification」のフラグメントのページで、文字列を表示させるだけでなく、フラグメント内でMainActivity
で指定するようなアクティビティを実行しようとしています。
具体的には、デフォルトのdashboard
で、ボタンを表示し、画面の遷移を行うということを実行したいです。
画面遷移に関しては、参考記事・[Android & Kotlin] Activityの遷移をさせるの通りに、Empty Activity
を選択してプロジェクトを作成した場合は、エラーなく実行することができています。
発生している問題・エラーメッセージ
画面遷移のアクティビティをdashboardフラグメントに組み込もうとしたところ、2つの問題が発生しました。
①個別のアクティビティを指定する(今回の場合は画面遷移)MainActivity.kt
を、DashboardFragment.kt
にどのように組み込めば良いかわからない
DashboardFragment.ktとDashboardViewModel.ktによって、dashboardフラグメントをクリックすると「This is dashboard Fragment」という文字列が出ていることは理解しています。
クラスの定義が Fragment()
となっているDashboardFragment.ktには、AppCompatActivity()
のアクティビティは書き込めないと思うので、どのようにフラグメントに組み込みたいMainActivity.ktとDashboardFragment.ktとDashboardViewModel.ktを組み合わせればいいのか、わからず困っています。
②個別のアクティビティを指定する(今回の場合は画面遷移)SubActivity.kt
について
2-1. AndroidManifest.xml
でフラグメントと組み合わせる場合は、現在の書き方で正しいのかどうか
2-2. SubActivity.kt
という名称で現在の階層構造のようにui
フォルダ下の各フラグメントのファイルにおいていいのか
エラーは出ていないが、似たようなことをやっているコードを見たことがないため、参考になる記事などがあれば教えていただきたいです。
該当のソースコード
フラグメントに組み込みたいMainActivity.kt
kotlin
1package your.package.name 2 3import androidx.appcompat.app.AppCompatActivity 4import android.os.Bundle 5import android.content.Intent 6import kotlinx.android.synthetic.main.activity_main.* 7 8class MainActivity : AppCompatActivity() { 9 10 override fun onCreate(savedInstanceState: Bundle?) { 11 super.onCreate(savedInstanceState) 12 setContentView(R.layout.activity_main) 13 14 sendButton.setOnClickListener { 15 val intent = Intent(application, SubActivity::class.java) 16 startActivity(intent) 17 } 18 } 19}
DashboardFragment.kt
Kotlin
1package com.example.fragact.ui.dashboard 2 3import android.os.Bundle 4import android.view.LayoutInflater 5import android.view.View 6import android.view.ViewGroup 7import android.widget.TextView 8import androidx.fragment.app.Fragment 9import androidx.lifecycle.Observer 10import androidx.lifecycle.ViewModelProviders 11import com.example.fragact.R 12 13class DashboardFragment : Fragment() { 14 15 private lateinit var dashboardViewModel: DashboardViewModel 16 17 override fun onCreateView( 18 inflater: LayoutInflater, 19 container: ViewGroup?, 20 savedInstanceState: Bundle? 21 ): View? { 22 dashboardViewModel = 23 ViewModelProviders.of(this).get(DashboardViewModel::class.java) 24 val root = inflater.inflate(R.layout.fragment_dashboard, container, false) 25 val textView: TextView = root.findViewById(R.id.text_dashboard) 26 dashboardViewModel.text.observe(this, Observer { 27 textView.text = it 28 }) 29 return root 30 } 31}
DashboardViewModel.kt
kotlin
1package com.example.fragact.ui.dashboard 2 3import androidx.lifecycle.LiveData 4import androidx.lifecycle.MutableLiveData 5import androidx.lifecycle.ViewModel 6 7class DashboardViewModel : ViewModel() { 8 9 private val _text = MutableLiveData<String>().apply { 10 value = "This is dashboard Fragment" 11 } 12 val text: LiveData<String> = _text 13}
app/java/com.example.fracact/ui/dashboard/
SubActivity.kt
package com.example.fragact.ui.dashboard import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_sub.* class SubActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_sub) returnButton.setOnClickListener{ finish() } } }
AndroidManifest.xml
xml
1<?xml version="1.0" encoding="utf-8"?> 2<manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.fragact"> 4 5 <application 6 android:allowBackup="true" 7 android:icon="@mipmap/ic_launcher" 8 android:label="@string/app_name" 9 android:roundIcon="@mipmap/ic_launcher_round" 10 android:supportsRtl="true" 11 android:theme="@style/AppTheme"> 12 <activity 13 android:name=".MainActivity" 14 android:label="@string/app_name"> 15 <intent-filter> 16 <action android:name="android.intent.action.MAIN" /> 17 18 <category android:name="android.intent.category.LAUNCHER" /> 19 </intent-filter> 20 </activity> 21 <activity 22 android:name=".SubActivity" 23 android:label="@string/app_name" > 24 </activity> 25 </application> 26 27</manifest>
試したこと
DashboardFragment.kt
などアクティビティに関わるプログラムを変更せず、layoutだけ変更した場合、アクティビティなしの遷移前の画面は表示することができました。
fragment_dashboard.xml
xml
1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <TextView 8 android:id="@+id/text_dashboard" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:layout_marginStart="8dp" 12 android:layout_marginTop="8dp" 13 android:layout_marginEnd="8dp" 14 android:textAlignment="center" 15 android:textSize="20sp" 16 app:layout_constraintEnd_toEndOf="parent" 17 app:layout_constraintStart_toStartOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 20 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 21 xmlns:tools="http://schemas.android.com/tools" 22 android:layout_width="match_parent" 23 android:layout_height="match_parent" 24 android:orientation="vertical" 25 android:gravity="center" 26 android:background="#dfe" 27 tools:context=".MainActivity"> 28 29 <TextView 30 android:text="@string/main" 31 android:textSize="30sp" 32 android:layout_margin="10dp" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" /> 35 36 <Button 37 android:id="@+id/sendButton" 38 android:text="@string/move" 39 android:textSize="30sp" 40 android:layout_margin="20dp" 41 android:layout_width="wrap_content" 42 android:layout_height="wrap_content" /> 43 44 </LinearLayout> 45 46 47</androidx.constraintlayout.widget.ConstraintLayout>
コメントを受けて試したこと
app/java/com.example.fragact/MainActivityに組み込みたいMainActivity.ktの内容を追記してみました。
MainActivity
package com.example.fragact import android.os.Bundle import com.google.android.material.bottomnavigation.BottomNavigationView import androidx.appcompat.app.AppCompatActivity import androidx.navigation.findNavController import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import android.content.Intent import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navView: BottomNavigationView = findViewById(R.id.nav_view) val navController = findNavController(R.id.nav_host_fragment) // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. val appBarConfiguration = AppBarConfiguration( setOf( R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications ) ) setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) sendButton.setOnClickListener { val intent = Intent(application, SubActivity::class.java) startActivity(intent) } } }
しかし、
sendButton.setOnClickListener { val intent = Intent(application, SubActivity::class.java) startActivity(intent) }
でsendButton
がUnresolved reference
となります。
layoutのactivity_main.xmlではなく、fragment_dashboard.xmlで「sendButton」を定義していることも原因かと考えられますが、フラグメントごとにアクティビティやレイアウトを設定するには他に方法がわからない状態です。
<Button android:id="@+id/sendButton" android:text="@string/move" android:textSize="30sp" android:layout_margin="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" />
補足情報(FW/ツールのバージョンなど)
Android Studio 3.5.3
あなたの回答
tips
プレビュー