来自MainActivity的Fragment中的调用方法 [英] Call method in Fragment from MainActivity
问题描述
我的应用程序由一个 MainActivity
组成,其中包含一个 TabLayout
.第二个选项卡具有 RecyclerView
,可通过单击选择项目.初始状态如左图所示.当一个或多个项目被选择然而,一个叠加<代码>工具栏代码>被示为具有的选项(从左至右)复制,编辑,删除或取消选择的项目.这种情况显示在中间图中.
My application consists of a MainActivity
that contains a TabLayout
. The second tab has a RecyclerView
which allows for items to be selected by clicking on them. The initial state is shown in the left figure. When one or more items are selected however, a overlaying Toolbar
is shown with the options to (from left to right) copy, edit, delete or deselect the items. This situation is shown in the middle figure.
当例如取消选定选项被选择时,在工具栏代码>应该隐藏和项目应被取消.问题是我不知道如何让
RecyclerView
的 ListAdapter
知道应该取消选择这些项目.选择取消选择选项的当前结果如右图所示,因此 Toolbar
隐藏,但不会取消选择项目.
When for example the deselect option is chosen, the Toolbar
should hide and the items should be deselected. The problem is that I do not know how to let the ListAdapter
of the RecyclerView
know that those items should be deselected.
The current result of chosing the deselect option is shown in the right figure, so the Toolbar
hides but the items do not get deselected.
困难在于, RecyclerView
位于第二个片段中,称为 Fragment2
,而带有选项的 Toolbar
是布局的一部分 MainActivity
的代码. Fragment2
包含方法 deselect
.此方法可以正常工作,但无法从 MainActivity
调用它.
The difficulty is that the RecyclerView
is in the second fragment, called Fragment2
, and the Toolbar
with the options is part of the layout of the MainActivity
. Fragment2
contains the method deselect
. This method works fine, but am not able to call it from the MainActivity
.
为解决这个问题,我尝试使用界面,但没有成功.第二种方法是在下面提供的代码中实现的.我试图在 onOptionsItemSelected
方法中调用 deselect
,但是它告诉我 fragment2 == null
.我也曾尝试做 Dimitar Darazhanski 提出的建议,但我不知道在哪里给出 fragment2
标签以及在我的情况下要使用的容器ID.
To solve this I have tried using an interface, but without success. The second way is as implemented in the code provided below. I am trying to call deselect
in the onOptionsItemSelected
method, but it tells me that fragment2 == null
. I have also tried to do what Dimitar Darazhanski suggests, but I cannot figure out where to give fragment2
a tag and what container id to use in my case.
如果您知道如何通过修改此方法或使用完全不同的方法来解决此问题,请告诉我!
If you know how to solve this by modifying this approach or using an entirely different approach, please let me know!
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;
}
}
}
Fragment2
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>
fragment2.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>
推荐答案
您可以使用的一种解决方案是 LocalBroadcastManager ,您可以在此问题中看到.
One solution you can use is LocalBroadcastManager as you can see in this question.
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);
}
当您从 MainActivity调用 callDeselectFromMainActivity 方法时.应在 Fragment2中调用 onReceive
方法.
When you call callDeselectFromMainActivity method from MainActivity. It should call onReceive
method in Fragment2.
这篇关于来自MainActivity的Fragment中的调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!