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

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

新規登録して質問してみよう
ただいま回答率
85.48%
タブ

コンテンツの上下左右に参照用のメニューを設けることで、複数の要素やページの表示を可能にするユーザーインターフェイスパターンのこと。メニューをクリックすると、一つの要素が可視化され、他の要素は見えなくなる。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

1617閲覧

アンドロイドスタジオのタブホストのタブ名を変更できる処理を追加したい

YonHan

総合スコア40

タブ

コンテンツの上下左右に参照用のメニューを設けることで、複数の要素やページの表示を可能にするユーザーインターフェイスパターンのこと。メニューをクリックすると、一つの要素が可視化され、他の要素は見えなくなる。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2021/12/24 06:09

前提・実現したいこと

アンドロイドスタジオのタブホストのタブ名を変更できる処理を追加したいです。

下のソースコードでは、まず名前を変えたいタブを長押しし、ダイアログを表示して、そこで入力された名前にタブの名前を変えるということを試しましたが、タブ名は変わりませんでした。

![イメージ説明

発生している問題・エラーメッセージ

タブの名前が変わらない。

該当のソースコード

Java

1tabView.setOnLongClickListener(new View.OnLongClickListener() { 2 3 @Override 4 public boolean onLongClick(View v) { 5 LayoutInflater factory = LayoutInflater.from(MainActivity.this); 6 final View inputView = factory.inflate(R.layout.dialog, null); 7 8 AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); 9 builder.setTitle("カテゴリ名変更"); 10 11 //editviewを追加 12 builder.setView(inputView); 13 builder.setNegativeButton("キャンセル", null); 14 builder.setPositiveButton("変更", new DialogInterface.OnClickListener() { 15 @Override 16 public void onClick(DialogInterface dialog, int whichButton) { 17 //TODO タブの名前変更 18 //変更押したときの処理 19 EditText et = (EditText)inputView.findViewById(R.id.editText1); 20 String text = et.getText().toString();//editviewに変更後のタブ名を記入(text) 21 22 Tab1.setIndicator(text);//ここでタブの名前を変更 23 } 24 }); 25 builder.show(); 26 return false; 27 } 28 });

補足情報(FW/ツールのバージョンなど)

Gradleバージョン:7.0.2

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

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

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

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

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

hoshi-takanori

2021/12/28 18:57

そのタブをどうやって作ってるかによるのでは…。
YonHan

2021/12/30 05:42

タブはAndroid StudioのTabHostというものを使って作っています。
hoshi-takanori

2021/12/31 12:46

こういう方法 https://stackoverflow.com/a/2292323/1019868 もあるようですが、TabHost の実装詳細に依存するのはよくない気がしますよね。とはいえ clearAllTabs() して addTab し直すのも現在表示されてるコンテンツの立場がなくなるし、TabHost の代替 (そもそも API 30 で deprecated ですし) を探すのが良いのかなぁ。(作り込まれてるアプリでは、大体こういう表示部品はカスタム化されてる気が…。)
YonHan

2022/01/03 03:07 編集

ありがとうございます。
guest

回答2

0

ベストアンサー

変更をどこかに保存して、再起動時にそれを読んで設定すれば良いのではと思います。


回答にしちゃったので、ついでに AndroidStudio のタブのプロジェクト雛形から、タイトルを修正・保存 (SharedPreferences) するコードを作りました。
タブは TagLayout 、ビューページャは ViewPager2 、ダイアログはフラグメント、バインディングは嫌いなので外しています^^;

MainActivity.java

java

1package com.teratail.q375388; 2 3import android.content.SharedPreferences; 4import android.os.Bundle; 5import android.view.*; 6 7import com.google.android.material.tabs.*; 8 9import androidx.appcompat.app.*; 10import androidx.lifecycle.ViewModelProvider; 11import androidx.viewpager2.widget.ViewPager2; 12 13import com.teratail.q375388.ui.main.*; 14 15public class MainActivity extends AppCompatActivity implements View.OnLongClickListener, TabTitleChangeDialogFragment.Listener { 16 17 private SharedPreferences sharedPreferences; 18 private TabLayout tabLayout; 19 private PageViewModel pageViewModel; 20 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 26 sharedPreferences = getSharedPreferences("TabTitles", MODE_PRIVATE); 27 28 pageViewModel = new ViewModelProvider(this).get(PageViewModel.class); 29 pageViewModel.restoreTabTitles(sharedPreferences, new String[]{ 30 getString(R.string.tab_text_1), getString(R.string.tab_text_2) 31 }); 32 33 ViewPager2 viewPager = findViewById(R.id.pager); 34 viewPager.setAdapter(new SectionsStateAdapter(this)); 35 36 tabLayout = findViewById(R.id.tablayout); 37 new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText(pageViewModel.getTabTitle(position))).attach(); 38 39 for(int i=0; i<tabLayout.getTabCount(); i++) { 40 View view = tabLayout.getTabAt(i).view; 41 view.setTag(i); 42 view.setOnLongClickListener(this); 43 } 44 } 45 46 @Override 47 public boolean onLongClick(View v) { 48 int tabIndex = (Integer)v.getTag(); 49 String title = pageViewModel.getTabTitle(tabIndex); 50 TabTitleChangeDialogFragment dialog = TabTitleChangeDialogFragment.newInstance(tabIndex, title); 51 dialog.show(getSupportFragmentManager(), "TabTitleChangeDialogFragment"); 52 return true; 53 } 54 55 @Override 56 public void onTabTitleChange(TabTitleChangeDialogFragment dialog) { 57 String title = dialog.getTitle(); 58 int tabIndex = dialog.getTabIndex(); 59 tabLayout.getTabAt(tabIndex).setText(title); //ここでタブの名前を変更 60 61 pageViewModel.setTabTitle(tabIndex, title); 62 pageViewModel.saveTabTitles(sharedPreferences); 63 } 64}

res/layout/activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.coordinatorlayout.widget.CoordinatorLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <com.google.android.material.appbar.AppBarLayout 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content" 13 android:theme="@style/Theme.Q375388.AppBarOverlay"> 14 15 <TextView 16 android:id="@+id/title" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:gravity="center" 20 android:minHeight="?actionBarSize" 21 android:padding="@dimen/appbar_padding" 22 android:text="@string/app_name" 23 android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title" /> 24 25 <com.google.android.material.tabs.TabLayout 26 android:id="@+id/tablayout" 27 android:layout_width="match_parent" 28 android:layout_height="wrap_content" /> 29 30 </com.google.android.material.appbar.AppBarLayout> 31 32 <androidx.viewpager2.widget.ViewPager2 33 android:id="@+id/pager" 34 android:layout_width="match_parent" 35 android:layout_height="match_parent" /> 36 37</androidx.coordinatorlayout.widget.CoordinatorLayout>

ui.main.PageViewModel.java

java

1package com.teratail.q375388.ui.main; 2 3import android.content.SharedPreferences; 4 5import androidx.lifecycle.ViewModel; 6 7public class PageViewModel extends ViewModel { 8 private String[] tabTitles; 9 10 public String getTabTitle(int index) { return tabTitles[index]; } 11 public void setTabTitle(int index, String title) { tabTitles[index] = title; } 12 13 public void restoreTabTitles(SharedPreferences sharedPreferences, String[] defaultTitles) { 14 tabTitles = new String[defaultTitles.length]; 15 16 if(sharedPreferences == null) { 17 for(int i=0; i<tabTitles.length; i++) { 18 tabTitles[i] = defaultTitles[i]; 19 } 20 } else { 21 for(int i=0; i<tabTitles.length; i++) { 22 tabTitles[i] = sharedPreferences.getString(getPreferencesKey(i), defaultTitles[i]); 23 } 24 } 25 } 26 public void saveTabTitles(SharedPreferences sharedPreferences) { 27 SharedPreferences.Editor editor = sharedPreferences.edit(); 28 editor.clear(); 29 for(int i=0; i<tabTitles.length; i++) { 30 editor.putString(getPreferencesKey(i), tabTitles[i]); 31 } 32 editor.commit(); 33 } 34 35 private String getPreferencesKey(int i) { return "tab"+(i+1); } 36}

ui.main.TabTitleChangeDialogFragment.java

java

1package com.teratail.q375388.ui.main; 2 3import android.app.Dialog; 4import android.content.*; 5import android.os.Bundle; 6import android.view.*; 7import android.widget.EditText; 8 9import androidx.annotation.Nullable; 10import androidx.appcompat.app.AlertDialog; 11import androidx.fragment.app.*; 12 13import com.teratail.q375388.R; 14 15public class TabTitleChangeDialogFragment extends DialogFragment { 16 public interface Listener { 17 void onTabTitleChange(TabTitleChangeDialogFragment dialog); 18 } 19 20 private static final String ARGS_TAB_INDEX = "TabIndex"; 21 private static final String ARGS_TITLE = "Title"; 22 23 public static TabTitleChangeDialogFragment newInstance(int tabIndex, String title) { 24 TabTitleChangeDialogFragment dialog = new TabTitleChangeDialogFragment(); 25 Bundle args = new Bundle(); 26 args.putInt(ARGS_TAB_INDEX, tabIndex); 27 args.putString(ARGS_TITLE, title); 28 dialog.setArguments(args); 29 return dialog; 30 } 31 32 private int tabIndex; 33 private String title; 34 private Listener listener; 35 private EditText editText; 36 37 @Override 38 public void onCreate(@Nullable Bundle savedInstanceState) { 39 super.onCreate(savedInstanceState); 40 Bundle args = getArguments(); 41 tabIndex = args.getInt(ARGS_TAB_INDEX); 42 title = args.getString(ARGS_TITLE); 43 } 44 45 public int getTabIndex() { return tabIndex; } 46 public String getTitle() { return editText.getText().toString(); } 47 48 @Override 49 public void onAttach(Context context) { 50 super.onAttach(context); 51 try { 52 listener = (Listener)context; 53 } catch (ClassCastException e) { 54 throw new ClassCastException(context.toString() + " must implement TabTitleChangeDialogListener"); 55 } 56 } 57 58 @Override 59 public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 60 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 61 LayoutInflater inflater = requireActivity().getLayoutInflater(); 62 View inputView = inflater.inflate(R.layout.fragment_tab_title_change_dialog, null); 63 editText = inputView.findViewById(R.id.editText1); 64 editText.setText(title); 65 editText.requestFocus(); 66 editText.setSelection(0, title.length()); 67 68 builder.setView(inputView) 69 .setTitle("カテゴリ名変更") 70 .setPositiveButton("変更", new DialogInterface.OnClickListener() { 71 public void onClick(DialogInterface dialog, int id) { 72 listener.onTabTitleChange(TabTitleChangeDialogFragment.this); 73 } 74 }) 75 .setNegativeButton("キャンセル", (dialog, id) -> TabTitleChangeDialogFragment.this.getDialog().cancel()); 76 return builder.create(); 77 } 78}

res/layout/fragment_tab_title_change_dialog.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".ui.main.TabTitleChangeDialogFragment"> 9 10 <EditText 11 android:id="@+id/editText1" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:ems="16" 15 android:singleLine="true" 16 app:layout_constraintLeft_toLeftOf="parent" 17 app:layout_constraintTop_toTopOf="parent" /> 18 19</androidx.constraintlayout.widget.ConstraintLayout>

投稿2022/01/05 11:13

編集2022/01/05 16:50
jimbe

総合スコア12646

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

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

jimbe

2022/01/05 11:19 編集

コメントのつもりが回答になってしまいました。失礼 (_ _;
jimbe

2022/01/05 16:48 編集

タブの中身のフラグメントとアダプタは文字数の関係で省略です。
YonHan

2022/01/07 05:08

これはTabHostで作る時も使えますか? 例えば、タブのプロジェクト雛形であればタブ名にそれぞれtab_text_1,tab_text_2というString値が設定されていますが、TabHostではIndicatorでタブ名を設定します。 せっかく作ってもらったものを参考にしきれず申し訳ないです._.
jimbe

2022/01/07 06:00

本件に対する本質は、どちらかというと SharedPreferences による保存の方ですが(^_^; ご提示のコードだけではアプリがどの様な構造に作られているのか分かりませんし、試していませんが、 TabHost と TabLayout は別物ですので、そのままは出来ないと思います。 ただ、 hoshi-takanori さんの言われた通り TabHost は非推奨になりますので、個人的には TabLayout に換えるのをオススメします。
guest

0

紹介していただいたサイトの通り、やってみたところ無事タイトル名は変わりました。
ありがとうございますm(._.)m
後は「アプリを再起動したときに変更が変わっていないようにすること」が必要そうです。

投稿2022/01/03 03:08

YonHan

総合スコア40

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問