質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

2163閲覧

Navigation Drawer Activityを利用時に同じアイテムを選択したときfragmentを再生成しないやり方

luckyclock

総合スコア74

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2020/02/19 07:16

編集2020/02/20 01:57

android studioのデフォルトで用意されているNavigation Drawer Activityを改造してアプリを作っているのですが、navigationViewでHOME→galally→HOMEなどと一度別のfragmentを経由して表示した場合は問題ないのですが、NavigationViewでHOME→HOMEと選び同じフラグメントに遷移するとHomeFragmentに書いたHandler内でのviewの更新がされなくなったり一部挙動がおかしくなってしまいます。

単純な解決方法としては
1.NavigationViewで表示しているアイテムと同じアイテムを選択したら何もしない
2.一度fragmentのインスタンスが生成されていたら再生成しない
上記二つ思いついたのですが、解決方法として正しいのかどうか。
そして実装上どのようにすれば実現できるか知りたいです。
1.の解決方法はデフォルトのテンプレートで各アイテムがfragmentタグでxmlに埋め込まれいるので難しいような気がしています。

補足
動きを見てみましたが
2回目に同じアイテムをタップした場合、新たに生成しようとonCreateが走ったあとすぐに最初に動いていたものを終了しようとonDestroyが走ってしまっています。
これは単純に上記の方法で解決できるのだろうか・・・
1.案で解決できそうですが、表示しているフラグメントと同じアイテム選択時は何も処理しないとかできますか?
静的なfragmentなのでもしかして大幅につくりかえないと駄目でしょうか?

MainActivity.java

java

1import android.Manifest; 2import android.content.Intent; 3import android.content.pm.PackageManager; 4import android.os.Bundle; 5 6import com.google.android.material.floatingactionbutton.FloatingActionButton; 7import com.google.android.material.snackbar.Snackbar; 8 9import android.view.MenuItem; 10import android.view.View; 11 12import androidx.annotation.NonNull; 13import androidx.core.app.ActivityCompat; 14import androidx.core.content.ContextCompat; 15import androidx.navigation.NavController; 16import androidx.navigation.Navigation; 17import androidx.navigation.ui.AppBarConfiguration; 18import androidx.navigation.ui.NavigationUI; 19 20import com.google.android.material.navigation.NavigationView; 21 22import androidx.drawerlayout.widget.DrawerLayout; 23 24import androidx.appcompat.app.AppCompatActivity; 25import androidx.appcompat.widget.Toolbar; 26 27import android.view.Menu; 28 29public class MainActivity extends AppCompatActivity { 30 31 private AppBarConfiguration mAppBarConfiguration; 32 33 @Override 34 protected void onCreate(Bundle savedInstanceState) { 35 super.onCreate(savedInstanceState); 36 setContentView(R.layout.activity_main); 37 Toolbar toolbar = findViewById(R.id.toolbar); 38 setSupportActionBar(toolbar); 39 FloatingActionButton fab = findViewById(R.id.fab); 40 fab.setOnClickListener(new View.OnClickListener() { 41 @Override 42 public void onClick(View view) { 43 Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 44 .setAction("Action", null).show(); 45 } 46 }); 47 DrawerLayout drawer = findViewById(R.id.drawer_layout); 48 NavigationView navigationView = findViewById(R.id.nav_view); 49 50 // Passing each menu ID as a set of Ids because each 51 // menu should be considered as top level destinations. 52 mAppBarConfiguration = new AppBarConfiguration.Builder( 53 R.id.nav_home, R.id.nav_graph, R.id.nav_slideshow, 54 R.id.nav_tools, R.id.nav_share, R.id.nav_send) 55 .setDrawerLayout(drawer) 56 .build(); 57 NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); 58 NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); 59 NavigationUI.setupWithNavController(navigationView, navController); 60 } 61 62 @Override 63 public boolean onCreateOptionsMenu(Menu menu) { 64 // Inflate the menu; this adds items to the action bar if it is present. 65 getMenuInflater().inflate(R.menu.main, menu); 66 return true; 67 } 68 69 @Override 70 public boolean onSupportNavigateUp() { 71 NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); 72 return NavigationUI.navigateUp(navController, mAppBarConfiguration) 73 || super.onSupportNavigateUp(); 74 } 75 76 @Override 77 protected void onDestroy() 78 { 79 super.onDestroy(); 80 } 81}

mobile_navigation.xml

XML

1<?xml version="1.0" encoding="utf-8"?> 2<navigation xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:id="@+id/mobile_navigation" 6 app:startDestination="@+id/nav_home"> 7 8 <fragment 9 android:id="@+id/nav_home" 10 android:name="XXX.ui.home.HomeFragment" 11 android:label="@string/menu_home" 12 tools:layout="@layout/fragment_home" /> 13 14 <fragment 15 android:id="@+id/nav_graph" 16 android:name="XXX.ui.graph.GraphFragment" 17 android:label="@string/menu_graph" 18 tools:layout="@layout/fragment_graph" /> 19 20 <fragment 21 android:id="@+id/nav_slideshow" 22 android:name="xxx.ui.slideshow.SlideshowFragment" 23 android:label="@string/menu_slideshow" 24 tools:layout="@layout/fragment_slideshow" /> 25 26 <fragment 27 android:id="@+id/nav_tools" 28 android:name="xxx.ui.tools.ToolsFragment" 29 android:label="@string/menu_tools" 30 tools:layout="@layout/fragment_tools" /> 31 32 <fragment 33 android:id="@+id/nav_share" 34 android:name="xxx.ui.share.ShareFragment" 35 android:label="@string/menu_share" 36 tools:layout="@layout/fragment_share" /> 37 38 <fragment 39 android:id="@+id/nav_send" 40 android:name="xxx.ui.send.SendFragment" 41 android:label="@string/menu_send" 42 tools:layout="@layout/fragment_send" /> 43</navigation>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakajika

2020/02/20 06:07

NavControllerを使っているということは静的なfragmentでは無いはずですね。
guest

回答1

0

ベストアンサー

1.NavigationViewで表示しているアイテムと同じアイテムを選択したら何もしない

NavigationUIのソースを見てみましたが、この中にMenuItemの選択チェック処理を挟むのはちょっと厳しそうなので、NavigationViewを拡張してアイテムの再選択時には通知しないクラスを実装するのが良さそうです。関連するIssueでもBottomNavigationViewのような機能(OnNavigationItemReselectedListener)が必要かも?という話になっています。
以下のようなクラスを実装してNavigationViewの代わりに使ってみてください。

java

1public class UnreselectableNavigationView extends NavigationView { 2 // コンストラクタ...(略) 3 4 @Override 5 public void setNavigationItemSelectedListener(final @Nullable OnNavigationItemSelectedListener listener) { 6 if (listener != null) { 7 super.setNavigationItemSelectedListener(new OnNavigationItemSelectedListener() { 8 @Override 9 public boolean onNavigationItemSelected(@NonNull MenuItem item) { 10 // アイテムが選択されていない場合のみ通知 11 if (!item.isChecked()) { 12 return listener.onNavigationItemSelected(item); 13 } 14 return false; 15 } 16 }); 17 } else { 18 super.setNavigationItemSelectedListener(null); 19 } 20 } 21}

投稿2020/02/20 06:04

編集2020/02/20 11:47
kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

luckyclock

2020/02/20 07:34

すみません初歩的なところで躓いています。 UnreselectableNavigationViewクラスのコンストラクタがないと怒られてしまいます。 public UnreselectableNavigationView(){ } there is no default constructor available in・・・ それから return listener.onNavigationItemSelected(item);の部分も Variable 'listener' accessed from within inner class, nieeds to be declared final となります。
kakajika

2020/02/20 11:50

> UnreselectableNavigationViewクラスのコンストラクタがないと怒られてしまいます。 Android Studioでエラーの赤線にカーソルを合わせるとコンストラクタを自動で追加するメニューが出ると思います。そちらで追加してください。 > Variable 'listener' accessed from within inner class, nieeds to be declared final 失礼しました、Java7以前だとこの場合finalが必要ですね。回答を修正しておきましたのでご確認ください。(Java8にすればeffectively finalなので省略できます)
luckyclock

2020/02/21 05:31

新規に作成したクラスを下記に置き換えて実行したところアプリが落ちてしまいます。 // NavigationView navigationView = findViewById(R.id.nav_view); UnreselectableNavigationView navigationView = findViewById(R.id.nav_view); logです。キャストできません的なエラーのようです。 java.lang.RuntimeException: Unable to start activity ComponentInfo{XXX}: java.lang.ClassCastException: com.google.android.material.navigation.NavigationView cannot be cast to xxx.UnreselectableNavigationView at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) Caused by: java.lang.ClassCastException: com.google.android.material.navigation.NavigationView cannot be cast to xxxx.UnreselectableNavigationView at xxx.MainActivity.onCreate(MainActivity.java:57) at android.app.Activity.performCreate(Activity.java:7009) at android.app.Activity.performCreate(Activity.java:7000) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)  at android.app.ActivityThread.-wrap11(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6494)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
kakajika

2020/02/22 04:20

カスタムViewを使うのは初めてでしょうか?レイアウトxmlに埋め込んであるNavigationViewを自作クラスに変える必要があります。また、今回はUnreselectableNavigationViewがNavigationViewを継承しているのでJava側の変更は必要ありません。
luckyclock

2020/02/23 23:39

たびたびすみません。 java側は元に戻して activity_main.xmlの <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> を <XXX.UnreselectableNavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> としてみましたがやはりアプリが落ちてしまいます。
kakajika

2020/03/01 22:27

「アプリが落ちてしまいます」だけでは何が起きているのか分からないので、エラーの内容等を載せてください。
luckyclock

2020/03/02 00:37

エラー内容になります。 2020-03-02 09:29:02.617 8283-8283/XXX E/AndroidRuntime: FATAL EXCEPTION: main Process: XXX, PID: 8283 java.lang.RuntimeException: Unable to start activity ComponentInfo{XXX.MainActivity}: android.view.InflateException: Binary XML file line #16: Binary XML file line #16: Error inflating class XXX.UnreselectableNavigationView at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) Caused by: android.view.InflateException: Binary XML file line #16: Binary XML file line #16: Error inflating class XXX.UnreselectableNavigationView Caused by: android.view.InflateException: Binary XML file line #16: Error inflating class XXX.UnreselectableNavigationView Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet] at java.lang.Class.getConstructor0(Class.java:2320) at java.lang.Class.getConstructor(Class.java:1725) at android.view.LayoutInflater.createView(LayoutInflater.java:615) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) at android.view.LayoutInflater.rInflate(LayoutInflater.java:863) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) at android.view.LayoutInflater.inflate(LayoutInflater.java:515) at android.view.LayoutInflater.inflate(LayoutInflater.java:423) at android.view.LayoutInflater.inflate(LayoutInflater.java:374) at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555) at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161) at XXX.MainActivity.onCreate(MainActivity.java:44) at android.app.Activity.performCreate(Activity.java:7009) at android.app.Activity.performCreate(Activity.java:7000) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) xmlの16行目の<XXX.UnreselectableNavigationView部分がエラーのようですが、XXX部分はパッケージとしています。
kakajika

2020/03/02 00:46

> Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet] とありますから、必要なコンストラクタが足りていないようです。Android Studioの機能でコンストラクタを追加する際に複数の候補が出ると思いますので、全て選択して追加してください。
luckyclock

2020/03/02 01:01

何度もありがとうございます! 同じアイテムが選択できなくなりうまくいきまいた。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問