Вызов метода Fragment из PopupMenu - PullRequest
0 голосов
/ 12 мая 2019

, поэтому я пытаюсь вызвать метод из моего класса фрагмента в классе активности.В моей деятельности у меня есть навигационное представление снизу (и PopupMenu в нем), из которого я пытаюсь вызвать метод из фрагмента.

Это моя деятельность с решением, которое я нашел, поиск в Google, но это не такработа для меня:

public class MenuActivity extends AppCompatActivity {

    MapFragment map = new MapFragment();
    TextView textView;
    Toolbar toolbar;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        ((TextView) toolbar.findViewById(R.id.text_main)).setText(MainActivity.selectedButton);

        Fragment selectedFragment = null;
        selectedFragment = new MapFragment();
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();


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

    }

    private BottomNavigationView.OnNavigationItemSelectedListener navListener =
            new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {

                    Fragment selectedFragment = null;

                    switch (menuItem.getItemId()){
                        case R.id.nav_map:
                            selectedFragment = new MapFragment();
                            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
                            break;
                        case R.id.nav_sensors:
                            selectedFragment = new SensorsFragment();
                            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
                            break;
                        case R.id.nav_apps:
                            PopupMenu popup = new PopupMenu(MenuActivity.this, findViewById(R.id.nav_apps));
                            MenuInflater inflater = popup.getMenuInflater();
                            inflater.inflate(R.menu.bottom_nav_menu, popup.getMenu());
                            popup.show();
                            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                                @Override
                                public boolean onMenuItemClick(MenuItem item) {
                                    switch (item.getItemId()){
                                        case R.id.nav_floor:
                                            map.test();
                                            //Toast.makeText(getApplicationContext(),"Floor",Toast.LENGTH_SHORT).show();
                                            break;
                                        case R.id.nav_room:
                                            Toast.makeText(getApplicationContext(),"Room",Toast.LENGTH_SHORT).show();
                                            break;
                                        case R.id.nav_search:
                                            Toast.makeText(getApplicationContext(),"Search",Toast.LENGTH_SHORT).show();
                                            break;

                    }

                    return true;
                }

            };
}

И мой фрагмент (у меня есть пара других методов для Карт в этом классе, но это тот, с которым я тестирую это):

public class MapFragment extends Fragment{

View mView;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_map, container, false);
        return mView;
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        }
    }

    public void test(){
        Toast.makeText(getActivity(),"Test",Toast.LENGTH_SHORT).show();
    }
}

Кроме того, файлы XML:

activity_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    >

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:elevation="4dp"
        android:id="@+id/toolbar">

        <TextView
            android:id="@+id/text_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16dp"
            android:layout_centerHorizontal="true"/>

    </android.support.v7.widget.Toolbar>

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottom_nav_map"
        android:layout_below="@+id/toolbar"/>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_nav_map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:menu="@menu/bottom_nav"
        app:itemIconTint="@drawable/bottom_nav_color"
        app:itemTextColor="@drawable/bottom_nav_color"
        android:background="@color/colorPrimary"
        app:labelVisibilityMode="labeled"
        />

</RelativeLayout>

фрагмент_карты.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.gms.maps.MapView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/map"
    />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/location_button"
        android:text="LOC"
        android:layout_gravity="bottom"
        />

</FrameLayout>

Подводя итог, я пытаюсь вызвать метод test ()когда я выбрал первый вариант во всплывающем меню.

1 Ответ

0 голосов
/ 12 мая 2019

Вы вызываете test для экземпляра фрагмента, который никогда не добавляется в диспетчер фрагментов.

// You initialize this field
MapFragment map = new MapFragment();

protected void onCreate(Bundle savedInstanceState) {
    ...
    // Then you initialize a new MapFragment you add to the fragment manager
    Fragment selectedFragment = null;
    selectedFragment = new MapFragment();
    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
}

...
// Then you call `test` on the instance that's not attached to anything
map.test();

Решение - использовать ОДИН фрагмент и ссылаться на него. Также вы должны быть осторожны, чтобы правильно сохранять и восстанавливать состояние фрагмента.

MapFragment map; // Declare but don't initialize here

protected void onCreate(Bundle savedInstanceState) {
    ...
    // Initialize fragment instead of creating a new one if there is no state already
    if (savedInstanceState == null) {
        map = new MapFragment();
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, map).commit();
    }
    else {
        // If there is state, the fragment will be restored by the system, so just
        // get a reference to it
        map = getSupportFragmentManager().findFragmentById(R.id.fragment_containter)
    }
}

...
// Now calling test on the correctly attached fragment should work
map.test();

Надеюсь, это поможет!

...