I have a ViewPager
in my MainActivity. Every page in it is a Fragment. So, everytime I swipe right or left, a new instance of the fragment is created and the fragment view is updated accordingly.
我的MainActivity中有一个ViewPager。其中的每一页都是片段。因此,每次向右或向左滑动时,都会创建一个新的片段实例,并相应地更新片段视图。
I also have two buttons: LEFT
and RIGHT
for navigation. These buttons are inside the Fragment, not in the Activity. A user can either swipe or alternatively press the relevant button to navigate between the pages.
我还有两个按钮:LEFT和RIGHT用于导航。这些按钮位于片段内,而不在活动中。用户可以滑动或者按相关按钮在页面之间导航。
Here's the problem: Since I'm changing the views through my MainActivity, how do I detect the onClick
events of those buttons in the Activity in order to update the fragment?
问题在于:由于我正在通过MainActivity更改视图,如何检测Activity中这些按钮的onClick事件以更新片段?
Here's the PagerAdapter
class (Removed all the irrelevant code from everywhere):
这是PagerAdapter类(从所有地方删除了所有不相关的代码):
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// logic part for the views.
return PlaceholderFragment.newInstance(sectionNumber, questionStatus, questionOrder, showNext, showPrevious);
}
And here's the PlaceHolderFragment
class:
这是PlaceHolderFragment类:
public class PlaceholderFragment extends Fragment{
//some global variables
public static PlaceholderFragment newInstance(int sectionNumber, int questionStatus, String questionOrder, boolean showNext, boolean showPrevious) {
PlaceholderFragment fragment = new PlaceholderFragment();
//setting up the arguments
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.explanation_fragment, container, false);
//code for filling up all the views
RightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//can I do something here?
}
});
return rootView;
}
}
MORE INFO: I have to keep the navigation buttons in the fragment itself and not in the activity.
更多信息:我必须将导航按钮保留在片段本身而不是活动中。
5 个解决方案
#1
7
In your fragment write one interface like:
在你的片段中写一个界面,如:
public class PlaceholderFragment extends Fragment{
private OnButtonClickListener mOnButtonClickListener;
interface OnButtonClickListener{
void onButtonClicked(View view);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mOnButtonClickListener = (OnButtonClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(((Activity) context).getLocalClassName()
+ " must implement OnButtonClickListener");
}
}
yourButtons.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnButtonClickListener.onButtonClicked(v);
}
});
}
And in your mainactivity:
在你的主要活动中:
class MainActivity extends AppCompatActivity implements OnButtonClickListener{
@Override
void onButtonClicked(View view){
int currPos=yourPager.getCurrentItem();
switch(view.getId()){
case R.id.leftNavigation:
//handle currPos is zero
yourPager.setCurrentItem(currPos-1);
break;
case R.id.rightNavigation:
//handle currPos is reached last item
yourPager.setCurrentItem(currPos+1);
break;
}
}
}
#2
1
Make a public method in your activity
在您的活动中制作公共方法
public void swipeRight(int x){
if(x < totalNumberOfFragment){
viewPager.setCurrentItem(x + 1);
}
}
public void swipeLeft(int x){
if(x > 0){
viewPager.setCurrentItem(x - 1);
}
}
You can call these method from your fragment button's click action
您可以从片段按钮的单击操作中调用这些方法
RightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Yes
((YourActivityClassName)getActivity()).swipeRight(position);
}
});
And do same for LeftButton
并为LeftButton做同样的事情
YourActivityClassName - Activity which is holding this viewPager fragment.
YourActivityClassName - 持有此viewPager片段的Activity。
position - position of your current fragment.
position - 当前片段的位置。
#3
0
You can add button in your activities xml as follows
您可以在活动xml中添加按钮,如下所示
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
</LinearLayout>
<ImageView
android:id="@+id/leftNavigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:padding="10dp"
android:src="@drawable/ic_chevron_left_black_24dp"
android:visibility="gone" />
<ImageView
android:id="@+id/rightNavigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:layout_weight="0"
android:gravity="center"
android:padding="10dp"
android:src="@drawable/ic_chevron_right_black_24dp" />
</FrameLayout>
#4
0
You can create special method in your parent Activity
like following:
您可以在父Activity中创建特殊方法,如下所示:
public class PagerActiviy extends Activity {
...
public void onFragmentNavigationButtonClick(View button) {
// Do your stuff here
}
...
}
Then in your fragments you can get your parent Activity
with getActivity()
method, cast it to the actual type and call the method:
然后在您的片段中,您可以使用getActivity()方法获取父Activity,将其强制转换为实际类型并调用方法:
public class PlaceholderFragment extends Fragment{
...
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.explanation_fragment, container, false);
//code for filling up all the views
RightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((PagerActvity) getActivity()).onFragmentNavigationButtonClick(v);
}
});
return rootView;
}
}
As a side note I should add that from your example it's not clear why do you need to keep your navigation buttons in the fragments and can't move them to the Activity
and manage them there.
作为旁注,我应该在您的示例中添加它,不清楚为什么您需要将导航按钮保留在片段中,并且无法将它们移动到Activity并在那里管理它们。
#5
0
You can send a broadcast upon button click inside the fragment like below:
您可以在片段内点击按钮时发送广播,如下所示:
Intent intent = new Intent();
intent.setAction(NUMBER_OF_RECEIVER_NEXT);
getActivity().sendBroadcast(intent);
Then in your main activity you catch the Intent and you set the current position of the pager to the desired number
然后在主活动中捕获Intent,并将寻呼机的当前位置设置为所需的数字
private class broadcastReceived extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String actionGet = intent.getAction();
if(actionGet.equals(NUMBER_OF_RECEIVER_NEXT)){
mPager.setCurrentItem(1);
Log.e("IntentNextPage","Received");
}
}
}
Do not forget to set a
别忘了设置一个
private static final String NUMBER_OF_RECEIVER_NEXT = "nextPage";
in both main activity and fragment and of course to register,unregister receiver to onResume and onPause methods.
在主要活动和片段中,当然要注册,取消注册接收器到onResume和onPause方法。
Also add an intent filter to the receiver in onCreate methd with the action specified as NUMBER_OF_RECEIVER_NEXT
同时在onCreate methd中为接收器添加一个intent过滤器,并将操作指定为NUMBER_OF_RECEIVER_NEXT
#1
7
In your fragment write one interface like:
在你的片段中写一个界面,如:
public class PlaceholderFragment extends Fragment{
private OnButtonClickListener mOnButtonClickListener;
interface OnButtonClickListener{
void onButtonClicked(View view);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mOnButtonClickListener = (OnButtonClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(((Activity) context).getLocalClassName()
+ " must implement OnButtonClickListener");
}
}
yourButtons.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnButtonClickListener.onButtonClicked(v);
}
});
}
And in your mainactivity:
在你的主要活动中:
class MainActivity extends AppCompatActivity implements OnButtonClickListener{
@Override
void onButtonClicked(View view){
int currPos=yourPager.getCurrentItem();
switch(view.getId()){
case R.id.leftNavigation:
//handle currPos is zero
yourPager.setCurrentItem(currPos-1);
break;
case R.id.rightNavigation:
//handle currPos is reached last item
yourPager.setCurrentItem(currPos+1);
break;
}
}
}
#2
1
Make a public method in your activity
在您的活动中制作公共方法
public void swipeRight(int x){
if(x < totalNumberOfFragment){
viewPager.setCurrentItem(x + 1);
}
}
public void swipeLeft(int x){
if(x > 0){
viewPager.setCurrentItem(x - 1);
}
}
You can call these method from your fragment button's click action
您可以从片段按钮的单击操作中调用这些方法
RightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Yes
((YourActivityClassName)getActivity()).swipeRight(position);
}
});
And do same for LeftButton
并为LeftButton做同样的事情
YourActivityClassName - Activity which is holding this viewPager fragment.
YourActivityClassName - 持有此viewPager片段的Activity。
position - position of your current fragment.
position - 当前片段的位置。
#3
0
You can add button in your activities xml as follows
您可以在活动xml中添加按钮,如下所示
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
</LinearLayout>
<ImageView
android:id="@+id/leftNavigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:padding="10dp"
android:src="@drawable/ic_chevron_left_black_24dp"
android:visibility="gone" />
<ImageView
android:id="@+id/rightNavigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:layout_weight="0"
android:gravity="center"
android:padding="10dp"
android:src="@drawable/ic_chevron_right_black_24dp" />
</FrameLayout>
#4
0
You can create special method in your parent Activity
like following:
您可以在父Activity中创建特殊方法,如下所示:
public class PagerActiviy extends Activity {
...
public void onFragmentNavigationButtonClick(View button) {
// Do your stuff here
}
...
}
Then in your fragments you can get your parent Activity
with getActivity()
method, cast it to the actual type and call the method:
然后在您的片段中,您可以使用getActivity()方法获取父Activity,将其强制转换为实际类型并调用方法:
public class PlaceholderFragment extends Fragment{
...
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.explanation_fragment, container, false);
//code for filling up all the views
RightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((PagerActvity) getActivity()).onFragmentNavigationButtonClick(v);
}
});
return rootView;
}
}
As a side note I should add that from your example it's not clear why do you need to keep your navigation buttons in the fragments and can't move them to the Activity
and manage them there.
作为旁注,我应该在您的示例中添加它,不清楚为什么您需要将导航按钮保留在片段中,并且无法将它们移动到Activity并在那里管理它们。
#5
0
You can send a broadcast upon button click inside the fragment like below:
您可以在片段内点击按钮时发送广播,如下所示:
Intent intent = new Intent();
intent.setAction(NUMBER_OF_RECEIVER_NEXT);
getActivity().sendBroadcast(intent);
Then in your main activity you catch the Intent and you set the current position of the pager to the desired number
然后在主活动中捕获Intent,并将寻呼机的当前位置设置为所需的数字
private class broadcastReceived extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String actionGet = intent.getAction();
if(actionGet.equals(NUMBER_OF_RECEIVER_NEXT)){
mPager.setCurrentItem(1);
Log.e("IntentNextPage","Received");
}
}
}
Do not forget to set a
别忘了设置一个
private static final String NUMBER_OF_RECEIVER_NEXT = "nextPage";
in both main activity and fragment and of course to register,unregister receiver to onResume and onPause methods.
在主要活动和片段中,当然要注册,取消注册接收器到onResume和onPause方法。
Also add an intent filter to the receiver in onCreate methd with the action specified as NUMBER_OF_RECEIVER_NEXT
同时在onCreate methd中为接收器添加一个intent过滤器,并将操作指定为NUMBER_OF_RECEIVER_NEXT