Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I ensure my spinner (inside menu) updates my menu title and ensure the title is displayed in full?

Edit: Upon Re-setting the emulator the code is working fine and the title updates instantly when a spinner item is selected. However, the title is still not being displayed in full

Edit 2: Upon Re-setting the emulator once more I am having the same issues again...

I have tried to implement a spinner inside my menu for my recordExerciseActivity.

recordExerciseActivity

Every time an item inside the spinner is selected, this is set as the new menu title.

The problem I am having is that the first time I open the activity and click on a spinner item the title is not updated. (The onItemSelected code does not run)

However, the second time it works perfectly fine.

Moreover, in activities which the exercise names are really long, it only displays the first few letters.

2

Sometimes only the first letter...

3

How can I ensure the spinner updates my menu title correctly every time? (displaying the full title as well).

Menu XML

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/spinner"
        android:background="#ffffff"
        app:actionViewClass="android.widget.Spinner"
        app:showAsAction="always"
        android:title="spinner Title" />
</menu>

RecordExerciseActivity


public class RecordExerciseActivity2 extends AppCompatActivity {

    List<String> allChildExerciseNames = new ArrayList<>();
    public static final String PARENT_EXERCISE_ID = "-999";
    public static final String EXTRA_DATE = "com.example.exerciseappv4.EXTRA_DATE";
    public static final String EXTRA_WEEK_DATES = "1";
    public static String EXTRA_JUNCTIONID = "EXERCISE_JUNCTION_ID";
    int parentExerciseID;
    private ChildExerciseViewModel childExerciseViewModel;
    String firstExerciseName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record_exercise);

        Intent intent = getIntent();
        if (intent.hasExtra(PARENT_EXERCISE_ID)) {
            parentExerciseID = Integer.parseInt(intent.getStringExtra(PARENT_EXERCISE_ID));
        }

        BottomNavigationView bottomNav = findViewById(R.id.top_navigation);
        bottomNav.setOnNavigationItemSelectedListener(navListener);

        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container2, new RecordExerciseFragment()).commit();

        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back);
        childExerciseViewModel = ViewModelProviders.of(this).get(ChildExerciseViewModel.class);
        childExerciseViewModel.getChildExerciseNameFromParentID(parentExerciseID).observe(this, this::setChildExerciseName);
        childExerciseViewModel.getAllchildExercisesFromParentID(parentExerciseID).observe(this, this::getAllChildExercisesFromParentID);

    }

    private BottomNavigationView.OnNavigationItemSelectedListener navListener =
            new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    Fragment selectedFragment = null;

                    switch (item.getItemId()) {
                        case R.id.nav_track:
                            selectedFragment = new RecordExerciseFragment();
                            break;
                        case R.id.nav_history:
                            selectedFragment = new RecordExerciseHistoryFragment();
                            break;
                        case R.id.nav_exercise_list:
                            selectedFragment = new ExerciseGraphFragment();
                            break;
                    }
                    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container2, selectedFragment).commit();

                    return true;
                }
            };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.record_exercise_menu, menu);

        MenuItem item = menu.findItem(R.id.spinner);
        Spinner spinner = (Spinner) item.getActionView();
        ArrayList<String> spinnerStringArray = new ArrayList<>();
        //Add your data to your array
        spinnerStringArray.addAll(allChildExerciseNames);

        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, allChildExerciseNames);
        spinner.setAdapter(spinnerAdapter);


        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Log.i("Spinner Item Selected", "TRUE");
                String selectedExercise = parent.getItemAtPosition(position).toString();
                setTitle(selectedExercise);

            }

            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        return true;
    }

    private void setChildExerciseName(String childExerciseName) {
        firstExerciseName = childExerciseName;
        setTitle(firstExerciseName);
    }

    private void getAllChildExercisesFromParentID(List<String> allChildExercisesReceived) {
        allChildExerciseNames.addAll(allChildExercisesReceived);
    }
}

like image 395
Josh Brett Avatar asked May 25 '20 12:05

Josh Brett


1 Answers

Try with this custom layout file for your Spinner :simple_spinner_item_custom.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_text_1"
    style="?android:attr/spinnerItemStyle"
    android:singleLine="false"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="none"
    android:textAlignment="inherit" />

This is the simple modification of original simple_spinner_item.xml file to make it work in your scenario with editing attributes such as android:singleLine="true" and android:ellipsize="marquee" which wouldn't let you show multiline text. Now, pass this layout as the argument in the ArrayAdapter constructor as :

ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this,
                R.layout.simple_spinner_item_custom, spinnerStringArray);

Note: There is no point in setting title of the Activity using setTitle() method. Thanks to the new LiveLayoutInspector feature in Android Studio 4.0, I found out that this Spinner(so will its parent i.e ActionMenuView ) will be stretched to fit the content inside it and title of Activity will be sandwiched. I tried to reduce the width of Spinner or ActionMenuView with no success. Sadly, this way, I think your back navigation button will also be hidden.Sandwiched title of the Activity Window Stretched Spinner

But again, if you use app:showAsAction="ifRoom|collapseActionView" attributes to the Spinnermenu, you will get more or less similar kind of UI. Play with such attributes until they fit into your need.

Another alternative that I can think of at this moment is to inflate a normal menu with down arrow as icon, then in onOptionsItemSelected, handle it to open a Popup menu which will show the list of items that currently your Spinner is showing. Then, handle the onClick of Popup again to change the title of Toolbar(because the title of Activity doesn't support multiline and it doesn't have any id, so that its object can't be created).

like image 112
cgb_pandey Avatar answered Nov 15 '22 14:11

cgb_pandey