Расширение viewpager с навигационным ящиком

На данный момент у меня есть класс Base Activity, который реализует панель действий во всех моих действиях, теперь я хочу добавить к этому базовому классу, чтобы он реализовал ящик навигации. Но наличие базовой активности, которая реализует ящик навигации, дает мне много противоречивых ошибок.

Моя основная цель состоит в том, чтобы активность viewpager расширила эту базовую активность, которая реализует ящик навигации, как я могу это сделать? или есть работа вокруг?

благодаря

3 ответа

Если вы ищете навигационный ящик поверх ViewPager, то что вы можете сделать:

Если вы не знаете о NavigationDrawer правильно, пожалуйста, проверьте эту ссылку (щелкните здесь), используйте этот код в своем относительном макете

<android.support.v4.widget.drawerlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/custom_drawer_layout">


 <relativelayout android:id="@+id/relative" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
 <android.support.v4.view.viewpager android:id="@+id/pager" android:layout_width="fill_parent" android:layout_height="fill_parent">
 <android.support.v4.view.pagertabstrip android:id="@+id/pager_tab_strip" android:layout_width="match_parent" android:layout_height="48sp" android:layout_gravity="top" android:background="@color/primary" android:paddingbottom="20dp" android:textappearance="@style/PagerTabStripText">

 </android.support.v4.view.pagertabstrip></android.support.v4.view.viewpager>


 </relativelayout>

 </android.support.v4.widget.drawerlayout>

Вот что вы получите:

1 - фрагмент, а 2 - viewPager


У меня была такая же проблема, и я только что ее исправил сегодня вечером.

У меня была панель просмотра пейджера/салфетки, которую я хотел добавить в навигационный ящик.

Я построил свой навигационный ящик, чтобы перейти к моему плейджеру в соответствии с этим руководством. когда я пытался расширить его до моего класса viewpager, мне пришлось удалить расширение "fragactivity" для "навигатора". это дало мне ту же проблему, что и сейчас. мне потребовалось 3 часа исследований, чтобы понять, что если я расширяю класс A в классе B, то до тех пор, пока класс A "расширяет" тот же "поддерживающий класс", который нужен классу B, тогда вы не будете иметь эту проблему с нулевым указателем.

здесь код: navigation_draw.xml


android java:

package com.navigation.drawer.activity;
/**
* @author dipenp
*
* This activity will add Navigation Drawer for our application and all the code related to navigation drawer.
* We are going to extend all our other activites from this BaseActivity so that every activity will have Navigation Drawer in it.
* This activity layout contain one frame layout in which we will add our child activity layout. 
*/
public class BaseActivity extends Activity {

/**
 * Frame layout: Which is going to be used as parent layout for child activity layout.
 * This layout is protected so that child activity can access this 
 * */
protected FrameLayout frameLayout;

/**
 * ListView to add navigation drawer item in it.
 * We have made it protected to access it in child class. We will just use it in child class to make item selected according to activity opened. 
 */

protected ListView mDrawerList;

/**
 * List item array for navigation drawer items.
 * */
protected String[] listArray = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };

/**
 * Static variable for selected item position. Which can be used in child activity to know which item is selected from the list. 
 * */
protected static int position;

/**
 * This flag is used just to check that launcher activity is called first time
 * so that we can open appropriate Activity on launch and make list item position selected accordingly. 
 * */
private static boolean isLaunch = true;

/**
 * Base layout node of this Activity. 
 * */
private DrawerLayout mDrawerLayout;

/**
 * Drawer listner class for drawer open, close etc.
 */
private ActionBarDrawerToggle actionBarDrawerToggle;


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

 frameLayout = (FrameLayout)findViewById(R.id.content_frame);
 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
 mDrawerList = (ListView) findViewById(R.id.left_drawer);

 // set a custom shadow that overlays the main content when the drawer opens
 //mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

 // set up the drawer list view with items and click listener
 mDrawerList.setAdapter(new ArrayAdapter<string>(this, R.layout.drawer_list_item, listArray));
 mDrawerList.setOnItemClickListener(new OnItemClickListener() {

 @Override
 public void onItemClick(AdapterView<!--?--> parent, View view,
 int position, long id) {

 openActivity(position);
 }
 });

 // enable ActionBar app icon to behave as action to toggle nav drawer
 getActionBar().setDisplayHomeAsUpEnabled(true);
 getActionBar().setHomeButtonEnabled(true);

 // ActionBarDrawerToggle ties together the the proper interactions between the sliding drawer and the action bar app icon
 actionBarDrawerToggle = new ActionBarDrawerToggle(
 this, /* host Activity */
 mDrawerLayout, /* DrawerLayout object */
 R.drawable.ic_launcher, /* nav drawer image to replace 'Up' caret */
 R.string.open_drawer, /* "open drawer" description for accessibility */
 R.string.close_drawer) /* "close drawer" description for accessibility */
 {
 @Override
 public void onDrawerClosed(View drawerView) {
 getActionBar().setTitle(listArray[position]);
 invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
 super.onDrawerClosed(drawerView);
 }

 @Override
 public void onDrawerOpened(View drawerView) {
 getActionBar().setTitle(getString(R.string.app_name));
 invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
 super.onDrawerOpened(drawerView);
 }

 @Override
 public void onDrawerSlide(View drawerView, float slideOffset) {
 super.onDrawerSlide(drawerView, slideOffset);
 }

 @Override
 public void onDrawerStateChanged(int newState) {
 super.onDrawerStateChanged(newState);
 }
 };
 mDrawerLayout.setDrawerListener(actionBarDrawerToggle);


 /**
 * As we are calling BaseActivity from manifest file and this base activity is intended just to add navigation drawer in our app.
 * We have to open some activity with layout on launch. So we are checking if this BaseActivity is called first time then we are opening our first activity.
 * */
 if(isLaunch){
 /**
 *Setting this flag false so that next time it will not open our first activity.
 *We have to use this flag because we are using this BaseActivity as parent activity to our other activity.
 *In this case this base activity will always be call when any child activity will launch.
 */
 isLaunch = false;
 openActivity(0);
 }
}

/**
 * @param position
 *
 * Launching activity when any list item is clicked.
 */
protected void openActivity(int position) {

 /**
 * We can set title & itemChecked here but as this BaseActivity is parent for other activity,
 * So whenever any activity is going to launch this BaseActivity is also going to be called and
 * it will reset this value because of initialization in onCreate method.
 * So that we are setting this in child activity. 
 */

 mDrawerLayout.closeDrawer(mDrawerList);
 BaseActivity.position = position; //Setting currently selected position in this field so that it will be available in our child activities.

 switch (position) {
 case 0:
 startActivity(new Intent(this, Item1Activity.class));
 break;
 case 1:
 startActivity(new Intent(this, Item2Activity.class));
 break;
 case 2:
 startActivity(new Intent(this, Item3Activity.class));
 break;
 case 3:
 startActivity(new Intent(this, Item4Activity.class));
 break;
 case 4:
 startActivity(new Intent(this, Item5Activity.class));
 break;

 default:
 break;
 }

 Toast.makeText(this, "Selected Item Position::"+position, Toast.LENGTH_LONG).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

 ***************().inflate(R.menu.main, menu);
 return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

 // The action bar home/up action should open or close the drawer.
 // ActionBarDrawerToggle will take care of this.
 if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
 return true;
 }

 switch (item.getItemId()) {
 case R.id.action_settings:
 return true;

 default:
 return super.onOptionsItemSelected(item);
 }
}

/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
 // If the nav drawer is open, hide action items related to the content view
 boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
 menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
 return super.onPrepareOptionsMenu(menu);
}

/* We can override onBackPressed method to toggle navigation drawer*/
@Override
public void onBackPressed() {
 if(mDrawerLayout.isDrawerOpen(mDrawerList)){
 mDrawerLayout.closeDrawer(mDrawerList);
 }else {
 mDrawerLayout.openDrawer(mDrawerList);
 }
}
}
</string>

мой код пейджера-адаптера (обратите внимание, что этот класс пейджера распространяется только на навигатор, и навигатор расширяет активность... это не сработает (ваша проблема), если вы измените "продление активности" в Navigator на "extends FragmentActivity", пейджер и ящик будут потому что этот просмотр пейджера использует FragmentActivity):

public class StartActive extends Navigator implements TabListener
{
MyAdapter adapt;
ActionBar actionBar;
ViewPager viewPager = null;
String userName;


@Override
protected void onCreate(Bundle savedInstanceState) 
{
 super.onCreate(savedInstanceState);
 //setContentView(R.layout.activity_start_active);
 getLayoutInflater().inflate(R.layout.activity_start_active, frameLayout);

 naviList.setItemChecked(position, true);
 setTitle(category[position]);
 if(getIntent().getExtras() != null)
 {
 userName = getIntent().getExtras().getString(MainActivity.KEY_USERNAME);
 }


 swipeTabs(); 

}



public void swipeTabs()
{

 FragmentManager fragMan = getSupportFragmentManager();
 actionBar = getActionBar();
 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 adapt = new MyAdapter(fragMan);
 viewPager = (ViewPager) findViewById(R.id.startActive_Activity);
 viewPager.setAdapter(adapt);
 viewPager.setOnPageChangeListener(new OnPageChangeListener() 
 {

 @Override
 public void onPageSelected(int arg0) 
 {

 actionBar.setSelectedNavigationItem(arg0);
 }

 @Override
 public void onPageScrolled(int arg0, float arg1, int arg2) 
 {


 }

 @Override
 public void onPageScrollStateChanged(int arg0) 
 {


 }
 });
 android.app.ActionBar.Tab tab1 = actionBar.newTab();
 tab1.setText("User");
 tab1.setTabListener(this);

 android.app.ActionBar.Tab tab2 = actionBar.newTab();
 tab2.setText("Maps");
 tab2.setTabListener(this);

 android.app.ActionBar.Tab tab3 = actionBar.newTab();
 tab3.setText("Feed");
 tab3.setTabListener(this);

 actionBar.addTab(tab1);
 actionBar.addTab(tab2);
 actionBar.addTab(tab3);

}


@Override
public boolean onCreateOptionsMenu(Menu menu) 
{

 // Inflate the menu; this adds items to the action bar if it is present.
 ***************().inflate(R.menu.start_active, menu);
 return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
 // Handle action bar item clicks here. The action bar will
 // automatically handle clicks on the Home/Up button, so long
 // as you specify a parent activity in AndroidManifest.xml.
 int id = item.getItemId();
 if (id == R.id.action_settings) {
 return true;
 }
 return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment 
{

 public PlaceholderFragment() 
 {

 }

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
 {
 View rootView = inflater.inflate(R.layout.fragment_start_active, container, false);
 Log.d("Life cycles", "onCreateView");
 return rootView;
 }

}

@Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) 
{
 viewPager.setCurrentItem(arg0.getPosition());
}
@Override
public void onTabSelected(Tab arg0, FragmentTransaction arg1) 
{
 viewPager.setCurrentItem(arg0.getPosition());
}
@Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) 
{

}

class MyAdapter extends FragmentPagerAdapter
{

 public MyAdapter(FragmentManager fm) 
 {
 super(fm);
 }

 @Override
 public Fragment getItem(int arg0) 
 {
 Bundle b = new Bundle();
 b.putString(MainActivity.KEY_USERNAME, userName);
 Fragment frag;
 switch(arg0)
 {
 case 1:
 return new GMaps();
 case 0:

 frag = new UserView();
 frag.setArguments(b);
 return frag;
 case 2:
 frag = new FeedView();
 frag.setArguments(b);
 return frag;
 }
 return null;

 }

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

}
}


Вот как я это делаю. Я точно не помню, где я его взял, но он также изменился. В моем случае я определил его как абстрактный и расширил мою MainActivity. Причиной было сохранить логику, связанную с DrawerActivity, в одном классе, чтобы она не смешивалась с моей бизнес-логикой.

public abstract class DrawerActivity extends BaseActivity {

 private ActionBarDrawerToggle mDrawerListener;
 private DrawerLayout mDrawerLayout;
 private ListView mDrawerList;
 private ListAdapter mDrawerListAdapter;

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

 mDrawerList = (ListView) findViewById(R.id.drawer_list);

 }

 @Override
 public void onSupportContentChanged() {
 super.onSupportContentChanged();
 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
 if (mDrawerLayout == null) {
 throw new RuntimeException(
 "Your layout must be a DrawerLayout"
 );
 }
 mDrawerList = (ListView) findViewById(R.id.drawer_list);
 if (mDrawerList == null) {
 throw new RuntimeException(
 "Your content must have a ListView"
 );
 }


 mDrawerListener = new ActionBarDrawerToggle(this, mDrawerLayout,
 R.string.drawer_open,
 R.string.drawer_close) {
 public void onDrawerClosed(View view) {
 onDrawerClose(view);
 }

 public void onDrawerOpened(View drawerView) {
 onDrawerOpen(drawerView);
 }

 };
 mDrawerLayout.setDrawerListener(mDrawerListener);
 mDrawerList.setOnItemClickListener(mOnClickListener);

 mDrawerList.setAdapter(mDrawerListAdapter);
 }


 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
 if (mDrawerListener.onOptionsItemSelected(item)) {
 return true;
 }
 return super.onOptionsItemSelected(item);
 }


 @Override
 protected void onPostCreate(Bundle savedInstanceState) {
 super.onPostCreate(savedInstanceState);
 mDrawerListener.syncState();
 }

 @Override
 public void onConfigurationChanged(Configuration newConfig) {
 super.onConfigurationChanged(newConfig);
 mDrawerListener.onConfigurationChanged(newConfig);
 }

 @Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
 ensureDrawerList();
 super.onRestoreInstanceState(savedInstanceState);
 }

 @Override
 protected void onResume() {
 super.onResume();
 mDrawerLayout.closeDrawer(mDrawerList);
 }

 @Override
 public void setContentView(int layoutResID) {
 setContentView(getLayoutInflater().inflate(layoutResID, null));
 }

 @SuppressLint("InflateParams")
 @Override
 public void setContentView(View view) {
 mDrawerLayout = (DrawerLayout) getLayoutInflater().inflate(
 R.layout.drawer_activity, null);
 FrameLayout layout = (FrameLayout) mDrawerLayout
 .findViewById(R.id.content_frame);
 layout.addView(view);
 super.setContentView(mDrawerLayout);
 }

 public void onDrawerToggle() {
 if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
 mDrawerLayout.closeDrawer(mDrawerList);
 } else {
 mDrawerLayout.openDrawer(mDrawerList);
 }
 }

 public void setDrawerListAdapter(ListAdapter adapter) {
 synchronized (this) {
 ensureDrawerList();
 mDrawerListAdapter = adapter;
 }
 }

 public void setDrawerListSelection(int position) {
 mDrawerList.setSelection(position);
 mDrawerList.setItemChecked(position, true);
 }

 public int getSelectedDrawerItemPosition() {
 return mDrawerList.getSelectedItemPosition();
 }

 public long getSelectedDrawerItemId() {
 return mDrawerList.getSelectedItemId();
 }

 protected void onListItemClick(ListView l, View v, int position, long id) {
 mDrawerList.setItemChecked(position, true);
 mDrawerLayout.closeDrawer(mDrawerList);
 }

 protected void onDrawerClose(View view) {
 supportInvalidateOptionsMenu();
 }

 protected void onDrawerOpen(View drawerView) {
 supportInvalidateOptionsMenu();
 }

 private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
 public void onItemClick(AdapterView<!--?--> parent, View v, int position,
 long id) {
 onListItemClick((ListView) parent, v, position, id);
 }
 };

 public boolean isDrawerOpen() {
 return mDrawerLayout.isDrawerOpen(mDrawerList);
 }

 private void ensureDrawerList() {
 if (mDrawerList != null) {
 return;
 }
 mDrawerList = (ListView) findViewById(R.id.drawer_list);
 }

 public ListView getDrawerList() {
 return mDrawerList;
 }
}

drawer_activity.xml:

<android.support.v4.widget.drawerlayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent">

 <!-- The main content view -->

 <framelayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="wrap_content">
 </framelayout>
 <!-- The navigation drawer -->

 </android.support.v4.widget.drawerlayout>

licensed under cc by-sa 3.0 with attribution.