Вызов метода во фрагменте из MainActivity - PullRequest
0 голосов
/ 21 декабря 2018

Мое приложение состоит из MainActivity, который содержит TabLayout.Вторая вкладка имеет RecyclerView, которая позволяет выбирать элементы, нажимая на них.Начальное состояние показано на левом рисунке.Однако, если выбран один или несколько элементов, отображается наложение Toolbar с вариантами (слева направо) копирования, редактирования, удаления или отмены выбора элементов.Эта ситуация показана на среднем рисунке.

Когда, например, выбран вариант отмены выбора, Toolbar должен скрыться, а элементы должны быть отменены.Проблема в том, что я не знаю, как дать ListAdapter из RecyclerView знать, что эти пункты должны быть отменены.Текущий результат выбора опции отмены выбора показан на правом рисунке, поэтому Toolbar скрывает, но элементы не отменяются.

enter image description here

Сложность заключается в том, что RecyclerView находится во втором фрагменте, называемом Fragment2, а Toolbar с параметрами является частью макета MainActivity.Fragment2 содержит метод deselect.Этот метод работает нормально, но я не могу вызвать его из MainActivity.

. Чтобы решить эту проблему, я попытался использовать интерфейс, но безуспешно.Второй способ реализован в приведенном ниже коде.Я пытаюсь вызвать deselect в методе onOptionsItemSelected, но он говорит мне, что fragment2 == null.Я также пытался сделать то, что предлагает Димитар Даражански , но я не могу понять, где дать fragment2 тег и какой идентификатор контейнера использовать в моем случае.

Если вы знаете, какЧтобы решить эту проблему путем изменения этого подхода или использования совершенно другого подхода, пожалуйста, дайте мне знать!

MainActivity

import android.animation.Animator;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.os.Build;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    ViewPager mViewPager;
    TabLayout tabLayout;
    Integer currentTab, fragmentID;
    boolean itemsSelected;

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


        mViewPager = findViewById(R.id.viewpager_main_activity);
        tabLayout = findViewById(R.id.tablayout_main_activity);
        tabLayout.setupWithViewPager(mViewPager);
        itemsSelected = false;

        displayDefaultAppbar();
        handleFragments(mViewPager);
        currentTab = handleStartupFragment(mViewPager, savedInstanceState);
    }

    private void displayDefaultAppbar() {
        final Toolbar toolbar = findViewById(R.id.toolbar_main_activity);
        TabLayout tabLayout = findViewById(R.id.tablayout_main_activity);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setTitle(getResources().getString(R.string.app_name));
        }
        toolbar.setVisibility(View.VISIBLE);
        tabLayout.setVisibility(View.VISIBLE);
    }

    private void handleFragments(ViewPager mViewPager) {
        SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mSectionsPagerAdapter);
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager) {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                super.onTabSelected(tab);
                int tabIconColor = ContextCompat.getColor(MainActivity.this, android.R.color.holo_red_dark);
                if(tab.getIcon() != null) {
                    tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
                }
                currentTab = tab.getPosition();
                handleToolbarOptions(currentTab);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                super.onTabUnselected(tab);
                int tabIconColor = ContextCompat.getColor(MainActivity.this, android.R.color.black);
                if(tab.getIcon() != null) {
                    tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
                }
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                super.onTabReselected(tab);
            }
        });
    }

    private Integer handleStartupFragment(ViewPager mViewPager, Bundle savedInstanceState) {
        Intent intent = getIntent();
        Integer startupFragment;
        tabLayout.getTabAt(0).setText("1");
        tabLayout.getTabAt(1).setText("2");
        tabLayout.getTabAt(2).setText("3");
        if(intent.hasExtra("initialFragment")){
            Bundle bd = getIntent().getExtras();
            startupFragment = bd.getInt("initialFragment");
        } else {
            startupFragment = 1;
        }
        if (savedInstanceState == null) {
            mViewPager.setCurrentItem(startupFragment);
        }
        return startupFragment;
    }

    @Override
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        fragmentID = fragment.getId();
    }

    private void handleToolbarOptions(Integer currentTab) {
        Toolbar toolbar = findViewById(R.id.toolbar_main_activity);
        if (currentTab == 1) {
            toolbar.getMenu().clear();
            toolbar.inflateMenu(R.menu.fragment2);
        } else {
            toolbar.getMenu().clear();
            toolbar.inflateMenu(R.menu.other);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Toolbar toolbar = findViewById(R.id.toolbar_main_activity_selected);
        if (toolbar.isShown()) {
            getMenuInflater().inflate(R.menu.selected, menu);
        } else if (currentTab == 1) {
            getMenuInflater().inflate(R.menu.fragment2, menu);
        } else {
            getMenuInflater().inflate(R.menu.other, menu);
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.selected_close) {
            if (findViewById(R.id.toolbar_main_activity_selected) != null) {
                hideSelectedToolbar();
                Fragment2 fragment2 = (Fragment2) getSupportFragmentManager().findFragmentById(R.id.tablayout_main_activity);
                if(fragment2 == null) {
                    Toast.makeText(this,"null",Toast.LENGTH_SHORT).show();
                } else if (!fragment2.isAdded()) {
                    Toast.makeText(this,"Not added",Toast.LENGTH_SHORT).show();
                } else {
                    fragment2.deselect();
                }
            }
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    public void displaySelectedToolbar() {
        final Toolbar toolbar = findViewById(R.id.toolbar_main_activity_selected);
        toolbar.setVisibility(View.VISIBLE);
        if (Build.VERSION.SDK_INT >= 21) {
            toolbar.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    Animator animator = ViewAnimationUtils.createCircularReveal(toolbar, toolbar.getWidth(), 0, 0,toolbar.getWidth());
                    animator.setDuration(ANIMATION_DURATION);
                    toolbar.removeOnLayoutChangeListener(this);
                    animator.start();
                }
            });
        }
        toolbar.setTitleTextColor(ContextCompat.getColor(MainActivity.this, android.R.color.black));
        setSupportActionBar(toolbar);
    }

    public void hideSelectedToolbar() {
        final Toolbar toolbar = findViewById(R.id.toolbar_main_activity_selected);
        if (Build.VERSION.SDK_INT >= 21) {
            Animator animator = ViewAnimationUtils.createCircularReveal(toolbar, toolbar.getWidth(), 0, toolbar.getWidth(), 0);
            animator.setDuration(ANIMATION_DURATION);
            animator.start();
            animator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {

                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    toolbar.setVisibility(View.GONE);
                    displayDefaultAppbar();
                }

                @Override
                public void onAnimationCancel(Animator animator) {

                }

                @Override
                public void onAnimationRepeat(Animator animator) {

                }
            });
        } else {
            toolbar.setVisibility(View.GONE);
            displayDefaultAppbar();
        }
    }

    private class SectionsPagerAdapter extends FragmentPagerAdapter {

        private SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new Fragment1();
                case 1:
                    return new Fragment2();
                case 2:
                    return new Fragment3();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return 3;
        }
    }
}

Фрагмент2

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import java.util.ArrayList;

public class Fragment2 extends Fragment {

    ListAdapter adapter;
    RecyclerView rv;
    ArrayList<TestItem> list;
    Integer selected, selectedOld;

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

        selected = 0;
        selectedOld = 0;

        list = new ArrayList<>();
        list.add(new TestItem("Item 1",false));
        list.add(new TestItem("Item 2",false));
        list.add(new TestItem("Item 3",false));
        list.add(new TestItem("Item 4",false));
        list.add(new TestItem("Item 5",false));
        list.add(new TestItem("Item 6",false));

        rv = rootView.findViewById(R.id.rv_fragment2);
        adapter = new ListAdapter(getActivity());
        rv.setAdapter(adapter);
        rv.setLayoutManager(new LinearLayoutManager(getActivity()));

        return rootView;
    }

    private void handleToolbar() {
        if (selected == 1 && selectedOld == 0) {
            if (getActivity() != null) {
                ((MainActivity) getActivity()).displaySelectedToolbar();
            }
        } else if (selected == 0 && selectedOld == 1) {
            if (getActivity() != null) {
                ((MainActivity) getActivity()).hideSelectedToolbar();
            }
        }
    }

    public void deselect() {
        for (int i=0; i<list.size(); i++) {
            list.get(i).setSelected(false);
        }
        adapter.notifyDataSetChanged();
        rv.setAdapter(adapter);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarlayout_main_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar_main_activity"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways|snap"
            android:background="?attr/colorPrimary"
            android:visibility="visible"/>

        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout_main_activity"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager_main_activity"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar_main_activity_selected"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorAccent"
        android:translationZ="4dp"
        android:visibility="invisible"/>

</android.support.design.widget.CoordinatorLayout>

фрагмент2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/root_fragment2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_fragment2"
        android:paddingTop="150dp"
        android:paddingBottom="10dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        android:splitMotionEvents="false"
        android:clipToPadding="false"/>

</LinearLayout>

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Вы можете добавить класс следующим образом:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;

public class MainTabsPagerAdapter extends FragmentStatePagerAdapter {

    int mNoOfTabs;

    private OneFragment oneFragment;
    private TwoFragment twoFragment;
    private ThreeFragment threeFragment;

    public MainTabsPagerAdapter(FragmentManager fm, int numberOfTabs) {
        super(fm);
        mNoOfTabs = numberOfTabs;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new oneFragment();
            case 1:
                return new twoFragment();
            case 2:
                return new threeFragment();
        }
        return null;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
        switch(position){
            case 0:
                oneFragment = (OneFragment) createdFragment;
                break;
            case(1):
                twoFragment = (TwoFragment) createdFragment;
                break;
            case(2):
                threeFragment = (ThreeFragment) createdFragment;
                break;
        }
        return createdFragment;
    }

    public OneFragment getOneFragment() {
        return oneFragment;
    }

    public TwoFragment getTwoFragment() {
        return twoFragment;
    }

    public ThreeFragment getThreeFragment() {
        return threeFragment;
    }

    @Override
    public int getCount() {
        return mNoOfTabs;
    }
}

После этого добавьте в свой MainActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    final String ONE_FRAGMENT = getString(R.string.one_fragment);
    final String TWO_FRAGMENT = getString(R.string.two_fragment);
    final String THREE_FRAGMENT = getString(R.string.three_fragment);

    mainTabLayout.addTab(mainTabLayout.newTab().setText(ONE_FRAGMENT));
    mainTabLayout.addTab(mainTabLayout.newTab().setText(TWO_FRAGMENT));
    mainTabLayout.addTab(mainTabLayout.newTab().setText(THREE_FRAGMENT));

    tabsPagerAdapter = new MainTabsPagerAdapter(getSupportFragmentManager(), mainTabLayout.getTabCount());
    mainViewPager.setAdapter(tabsPagerAdapter);
    mainViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mainTabLayout));
    mainTabLayout.addOnTabSelectedListener(this);
}

@Override
public void onTabSelected(TabLayout.Tab tab) {
    mainViewPager.setCurrentItem(tab.getPosition());
    mainToolbar.setTitle(firstCharToUpperCase(String.valueOf(tab.getText())));
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {

}

@Override
public void onTabReselected(TabLayout.Tab tab) {

}

Если вы хотите получить, например, OneFragment, вы можете позвонить:

OneFragment oneFragment = tabsPagerAdapter.getOneFragment();
oneFragment.doSomething();
0 голосов
/ 21 декабря 2018

Одно из решений, которое вы можете использовать: LocalBroadcastManager , как вы можете видеть в этого вопроса.

Fragment2

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // you will be notified here, you can do your stuff(deselect) here
            String message = intent.getStringExtra("my_message");
            Log.d("receiver_message", "my_message = " + message);
        }
    };

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

        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMessageReceiver,
                new IntentFilter("my_event_tag"));

        return rootView;

    }

    @Override
    public void onDestroy() {
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mMessageReceiver);
        super.onDestroy();
    }

MainActivity

private void callDeselectFromMainActivity() {
    Intent intent = new Intent("my_event_tag");
    intent.putExtra("my_message", "This is text should go to fragment...");
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

При вызове callDeselectFromMainActivity метод из MainActivity. Он должен вызывать onReceive метод в Fragment2.

...