I was dealing with this one in project I am currently working on and came up with following code. Maybe it's not relevant for you now, but it could help someone new in this post. :)
Basically it's ViewPager implementation as you mention in your answer, but I think it's the simplest and quickest solution to your question. The cons are that it's only for Fragments (could be easily changed for Objects) and if you want to add ActionBar into swipe, you probably end up creating a custom one.
public class DoubleViewPager extends FrameLayout implements ViewPager.OnPageChangeListener {
/**
* Represents number of objects in DelegateViewPager. In others words it stands for one main content
* window and one content detail window
*/
private static final int SCREEN_COUNT = 2;
private static final int CONTENT_SCREEN = 0;
private static final int DETAIL_SCREEN = 1;
private DelegateViewPager delegateViewPager;
private SparseArray<Fragment> activeScreens = new SparseArray<Fragment>(SCREEN_COUNT) ;
private DelegateAdapter adapter;
public DoubleViewPager(Context context) {
this(context, null);
}
public DoubleViewPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DoubleViewPager(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
delegateViewPager = new DelegateViewPager(context);
delegateViewPager.setId(R.id.main_page_id);
delegateViewPager.setOverScrollMode(ViewPager.OVER_SCROLL_NEVER);
final FrameLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER);
addView(delegateViewPager, params);
}
/**
* Create a new PagerAdapter and set content fragment as a first object in ViewPager;
* @param fragment Fragment you want to use as a main content
* @param fm FragmentManager required for ViewPager transactions
*/
public void initialize(final Fragment fragment, final FragmentManager fm) {
adapter = new DelegateAdapter(fm);
delegateViewPager.setAdapter(adapter);
activeScreens.put(CONTENT_SCREEN, fragment);
adapter.notifyDataSetChanged();
}
/**
* Adds fragment to stack and set it as current selected item. Basically it the same thing as calling
* startActivity() with some transitions effects
* @param fragment Fragment you want go into
*/
public void openDetailScreen(Fragment fragment) {
activeScreens.put(DETAIL_SCREEN, fragment);
adapter.notifyDataSetChanged();
delegateViewPager.setCurrentItem(1, true);
}
public void hideDetailScreen() {
delegateViewPager.setCurrentItem(CONTENT_SCREEN);
if (activeScreens.get(DETAIL_SCREEN) != null) {
activeScreens.remove(DETAIL_SCREEN);
adapter.notifyDataSetChanged();
}
}
@Override
public void onPageScrolled(int i, float v, int i2) {
// unused
}
@Override
public void onPageSelected(int i) {
if (i == CONTENT_SCREEN) hideDetailScreen();
}
@Override
public void onPageScrollStateChanged(int i) {
// unused
}
private class DelegateViewPager extends ViewPager {
public DelegateViewPager(Context context) {
super(context);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return getCurrentItem() != CONTENT_SCREEN && super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return getCurrentItem() != CONTENT_SCREEN && super.onTouchEvent(event);
}
}
private final class DelegateAdapter extends FragmentPagerAdapter {
public DelegateAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
return activeScreens.get(i);
}
@Override
public int getCount() {
return activeScreens.size();
}
}
}
Here is activity which implements it with another ViewPager as a SlidingMenu. (as extra)
public class DoubleViewPagerActivity extends FragmentActivity {
DoubleViewPager doubleViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_double_view_pager);
doubleViewPager = (DoubleViewPager) findViewById(R.id.doublePager);
doubleViewPager.initialize(new MainContentFragment(), getSupportFragmentManager());
}
public static final class MainContentFragment extends Fragment {
public MainContentFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_doublepager_content_window, parent, false);
final ViewPager pager = (ViewPager) view.findViewById(R.id.contentPager);
pager.setAdapter(new SimpleMenuAdapter(getChildFragmentManager()));
pager.setOffscreenPageLimit(2);
pager.setCurrentItem(1);
return view;
}
}
public static final class SimpleMenuAdapter extends FragmentPagerAdapter {
public SimpleMenuAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
return DoubleViewPagerActivity.PagerFragment.instance(i);
}
@Override
public int getCount() {
return 3;
}
@Override
public float getPageWidth(int position) {
switch (position) {
case 0:
case 2:
return 0.7f;
}
return super.getPageWidth(position);
}
}
public static final class PagerFragment extends Fragment {
public static PagerFragment instance(int position) {
final PagerFragment fr = new PagerFragment();
Bundle args = new Bundle();
args.putInt("position", position);
fr.setArguments(args);
return fr;
}
public PagerFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
final FrameLayout fl = new FrameLayout(getActivity());
fl.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
int position = getArguments().getInt("position");
switch (position) {
case 0:
fl.setBackgroundColor(Color.RED);
break;
case 1:
fl.setBackgroundColor(Color.GREEN);
initListView(fl);
break;
case 2:
fl.setBackgroundColor(Color.BLUE);
break;
}
return fl;
}
private void initListView(FrameLayout fl) {
int max = 50;
final ArrayList<String> items = new ArrayList<String>(max);
for (int i = 1; i <= max; i++) {
items.add("Items " + i);
}
ListView listView = new ListView(getActivity());
fl.addView(listView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, items));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
((DoubleViewPagerActivity) getActivity()).doubleViewPager.openDetailScreen(new DetailFragment());
}
});
}
}
public final static class DetailFragment extends Fragment {
public DetailFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
FrameLayout l = new FrameLayout(getActivity());
l.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
l.setBackgroundColor(getResources().getColor(android.R.color.holo_purple));
return l;
}
}
}
ViewPager
? – Similarity