├── image.png ├── res ├── layout │ └── example_activity.xml └── layout-land │ └── example_activity.xml ├── .gitignore ├── AndroidManifest.xml ├── README.md ├── pom.xml └── src └── main └── java └── com └── jakewharton └── example └── ExampleActivity.java /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JakeWharton/adjacent-fragment-pager-sample/HEAD/image.png -------------------------------------------------------------------------------- /res/layout/example_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Android generated 2 | bin 3 | gen 4 | lint.xml 5 | project.properties 6 | 7 | #Eclipse 8 | .project 9 | .classpath 10 | .settings 11 | .checkstyle 12 | 13 | #IntelliJ IDEA 14 | .idea 15 | *.iml 16 | *.ipr 17 | *.iws 18 | classes 19 | gen-external-apklibs 20 | 21 | #Maven 22 | target 23 | release.properties 24 | pom.xml.* 25 | 26 | website/_site 27 | 28 | #Ant 29 | build.xml 30 | local.properties 31 | proguard.cfg 32 | 33 | #Other 34 | .DS_Store 35 | tmp 36 | -------------------------------------------------------------------------------- /res/layout-land/example_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Adjacent Fragment Pager Sample 2 | ============================== 3 | 4 | Demonstrates how to manage two fragments where portrait displays them in a `ViewPager` and landscape 5 | displays them side-by-side. 6 | 7 | Due the shenanigans performed by `FragmentPagerAdapter` we're forced to write a custom 8 | `PagerAdapter` which handles the instances our selves. 9 | 10 | This sample is very-much hard coded and specific to two pages. If you wanted something a bit more 11 | robust and generalized it wouldn't be too much work to do so. 12 | 13 | ![Image](image.png) 14 | 15 | 16 | 17 | *Note: Requires r12 of the support-v4 library that is not available in Maven central.* 18 | 19 | 20 | 21 | 22 | License 23 | ------- 24 | 25 | Copyright 2013 Jake Wharton 26 | 27 | Licensed under the Apache License, Version 2.0 (the "License"); 28 | you may not use this file except in compliance with the License. 29 | You may obtain a copy of the License at 30 | 31 | http://www.apache.org/licenses/LICENSE-2.0 32 | 33 | Unless required by applicable law or agreed to in writing, software 34 | distributed under the License is distributed on an "AS IS" BASIS, 35 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | See the License for the specific language governing permissions and 37 | limitations under the License. 38 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.jakewharton.example 8 | adjacent-fragment-pager-sample 9 | apk 10 | 1.0.0-SNAPSHOT 11 | Adjacent Fragment Pager Sample 12 | 13 | 14 | UTF-8 15 | UTF-8 16 | 17 | 1.6 18 | 4.1.1.4 19 | 16 20 | r12 21 | 22 | 23 | 24 | 25 | com.google.android 26 | android 27 | ${android.version} 28 | provided 29 | 30 | 31 | com.google.android 32 | support-v4 33 | ${android.support.version} 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-compiler-plugin 42 | 3.0 43 | 44 | ${java.version} 45 | ${java.version} 46 | 47 | 48 | 49 | 50 | com.jayway.maven.plugins.android.generation2 51 | android-maven-plugin 52 | 3.5.2 53 | true 54 | 55 | 56 | ${android.platform} 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/main/java/com/jakewharton/example/ExampleActivity.java: -------------------------------------------------------------------------------- 1 | package com.jakewharton.example; 2 | 3 | import android.graphics.drawable.ColorDrawable; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentActivity; 7 | import android.support.v4.app.FragmentManager; 8 | import android.support.v4.app.FragmentTransaction; 9 | import android.support.v4.view.PagerAdapter; 10 | import android.support.v4.view.ViewPager; 11 | import android.util.Log; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.ImageView; 16 | import com.jakewharton.example.adjacent.R; 17 | 18 | public class ExampleActivity extends FragmentActivity { 19 | private static final String TAG = "XXXXXXX"; 20 | private static final String TAG_ONE = "one"; 21 | private static final String TAG_TWO = "two"; 22 | private static final int COLOR_ONE = 0xFF00FF00; 23 | private static final int COLOR_TWO = 0xFF0000FF; 24 | private static final String KEY_PAGE = "selected_page"; 25 | 26 | private ViewPager pager; 27 | private int lastPage; // If landscape, page from portrait. 28 | 29 | @Override protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | 32 | if (savedInstanceState != null) { 33 | lastPage = savedInstanceState.getInt(KEY_PAGE, 0); 34 | } 35 | 36 | setContentView(R.layout.example_activity); 37 | 38 | FragmentManager fragmentManager = getSupportFragmentManager(); 39 | 40 | Fragment one = fragmentManager.findFragmentByTag(TAG_ONE); 41 | Fragment two = fragmentManager.findFragmentByTag(TAG_TWO); 42 | 43 | FragmentTransaction remove = fragmentManager.beginTransaction(); 44 | if (one == null) { 45 | one = ColorFragment.newInstance(COLOR_ONE); 46 | Log.d(TAG, "Creating new fragment one."); 47 | } else { 48 | remove.remove(one); 49 | Log.d(TAG, "Found existing fragment one."); 50 | } 51 | if (two == null) { 52 | two = ColorFragment.newInstance(COLOR_TWO); 53 | Log.d(TAG, "Creating new fragment two."); 54 | } else { 55 | remove.remove(two); 56 | Log.d(TAG, "Found existing fragment two."); 57 | } 58 | if (!remove.isEmpty()) { 59 | remove.commit(); 60 | fragmentManager.executePendingTransactions(); 61 | } 62 | 63 | pager = (ViewPager) findViewById(R.id.pager); 64 | if (pager != null) { 65 | pager.setAdapter(new TwoFragmentAdapter(fragmentManager, one, two)); 66 | pager.setCurrentItem(lastPage); 67 | } else { 68 | fragmentManager.beginTransaction() 69 | .add(R.id.left_pane, one, TAG_ONE) 70 | .add(R.id.right_pane, two, TAG_TWO) 71 | .commit(); 72 | } 73 | } 74 | 75 | @Override protected void onSaveInstanceState(Bundle outState) { 76 | super.onSaveInstanceState(outState); 77 | if (pager != null) { 78 | outState.putInt(KEY_PAGE, pager.getCurrentItem()); 79 | } else { 80 | outState.putInt(KEY_PAGE, lastPage); 81 | } 82 | } 83 | 84 | private static class TwoFragmentAdapter extends PagerAdapter { 85 | private final FragmentManager fragmentManager; 86 | private final Fragment one; 87 | private final Fragment two; 88 | private FragmentTransaction currentTransaction = null; 89 | private Fragment currentPrimaryItem = null; 90 | 91 | public TwoFragmentAdapter(FragmentManager fragmentManager, Fragment one, Fragment two) { 92 | this.fragmentManager = fragmentManager; 93 | this.one = one; 94 | this.two = two; 95 | } 96 | 97 | @Override public int getCount() { 98 | return 2; 99 | } 100 | 101 | @Override public Object instantiateItem(ViewGroup container, int position) { 102 | if (currentTransaction == null) { 103 | currentTransaction = fragmentManager.beginTransaction(); 104 | } 105 | 106 | String tag = (position == 0) ? TAG_ONE : TAG_TWO; 107 | Fragment fragment = (position == 0) ? one : two; 108 | currentTransaction.add(container.getId(), fragment, tag); 109 | if (fragment != currentPrimaryItem) { 110 | fragment.setMenuVisibility(false); 111 | fragment.setUserVisibleHint(false); 112 | } 113 | 114 | return fragment; 115 | } 116 | 117 | @Override public void destroyItem(ViewGroup container, int position, Object object) { 118 | // With two pages, fragments should never be destroyed. 119 | throw new AssertionError(); 120 | } 121 | 122 | @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { 123 | Fragment fragment = (Fragment) object; 124 | if (fragment != currentPrimaryItem) { 125 | if (currentPrimaryItem != null) { 126 | currentPrimaryItem.setMenuVisibility(false); 127 | currentPrimaryItem.setUserVisibleHint(false); 128 | } 129 | if (fragment != null) { 130 | fragment.setMenuVisibility(true); 131 | fragment.setUserVisibleHint(true); 132 | } 133 | currentPrimaryItem = fragment; 134 | } 135 | } 136 | 137 | @Override public void finishUpdate(ViewGroup container) { 138 | if (currentTransaction != null) { 139 | currentTransaction.commitAllowingStateLoss(); 140 | currentTransaction = null; 141 | fragmentManager.executePendingTransactions(); 142 | } 143 | } 144 | 145 | @Override public boolean isViewFromObject(View view, Object object) { 146 | return ((Fragment) object).getView() == view; 147 | } 148 | } 149 | 150 | public static class ColorFragment extends Fragment { 151 | private static final String KEY_COLOR = "color"; 152 | private static final int DEFAULT_COLOR = 0xFFFF0000; 153 | 154 | public static ColorFragment newInstance(int color) { 155 | Bundle arguments = new Bundle(); 156 | arguments.putInt(KEY_COLOR, color); 157 | 158 | ColorFragment fragment = new ColorFragment(); 159 | fragment.setArguments(arguments); 160 | return fragment; 161 | } 162 | 163 | @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, 164 | Bundle savedInstanceState) { 165 | Bundle arguments = getArguments(); 166 | int color = arguments.getInt(KEY_COLOR, DEFAULT_COLOR); 167 | 168 | ImageView iv = new ImageView(getActivity()); 169 | iv.setImageDrawable(new ColorDrawable(color)); 170 | return iv; 171 | } 172 | } 173 | } 174 | --------------------------------------------------------------------------------