我知道此问题已经被问到here和here,但我仍然无法使用句柄创建导航抽屉。
我使用了下面提到的类::
DrawerHandle ::
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class DrawerHandle implements DrawerLayout.DrawerListener {
public static final String TAG = "DrawerHandle";
private ViewGroup mRootView;
private DrawerLayout mDrawerLayout;
private View mHandle;
private View mDrawer;
private float mVerticalOffset;
private int mGravity;
private WindowManager mWM;
private Display mDisplay;
private Point mScreenDimensions = new Point();
private OnClickListener mHandleClickListener = new OnClickListener(){
@Override
public void onClick(View v) {
if(!mDrawerLayout.isDrawerOpen(mGravity)) mDrawerLayout.openDrawer(mGravity);
else mDrawerLayout.closeDrawer(mGravity);
}
};
private OnTouchListener mHandleTouchListener = new OnTouchListener() {
private static final int MAX_CLICK_DURATION = 200;
private long startClickTime;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startClickTime = System.currentTimeMillis();
break;
}
case MotionEvent.ACTION_UP: {
if(System.currentTimeMillis() - startClickTime < MAX_CLICK_DURATION) {
v.performClick();
return true;
}
}
}
MotionEvent copy = MotionEvent.obtain(event);
copy.setEdgeFlags(ViewDragHelper.EDGE_ALL);
copy.setLocation(event.getRawX() + (mGravity == Gravity.LEFT || mGravity == GravityCompat.START ? -mHandle.getWidth()/2 : mHandle.getWidth() / 2), event.getRawY());
mDrawerLayout.onTouchEvent(copy);
copy.recycle();
return true;
}
};
private int getDrawerViewGravity(View drawerView) {
final int gravity = ((DrawerLayout.LayoutParams) drawerView.getLayoutParams()).gravity;
return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(drawerView));
}
private float getTranslation(float slideOffset){
return (mGravity == GravityCompat.START || mGravity == Gravity.LEFT) ? slideOffset*mDrawer.getWidth() : -slideOffset*mDrawer.getWidth();
}
@SuppressLint("NewApi")
private void updateScreenDimensions() {
if (Build.VERSION.SDK_INT >= 13) {
mDisplay.getSize(mScreenDimensions);
} else {
mScreenDimensions.x = mDisplay.getWidth();
mScreenDimensions.y = mDisplay.getHeight();
}
}
private DrawerHandle(DrawerLayout drawerLayout, View drawer, int handleLayout, float handleVerticalOffset) {
mDrawer = drawer;
mGravity = getDrawerViewGravity(mDrawer);
mDrawerLayout = drawerLayout;
mRootView = (ViewGroup)mDrawerLayout.getRootView();
LayoutInflater inflater = (LayoutInflater) mDrawerLayout.getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
mHandle = inflater.inflate(handleLayout, mRootView, false);
mWM = (WindowManager) mDrawerLayout.getContext().getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWM.getDefaultDisplay();
mHandle.setOnClickListener(mHandleClickListener);
mHandle.setOnTouchListener(mHandleTouchListener);
mRootView.addView(mHandle, new FrameLayout.LayoutParams(mHandle.getLayoutParams().width, mHandle.getLayoutParams().height, mGravity));
setVerticalOffset(handleVerticalOffset);
mDrawerLayout.setDrawerListener(this);
}
public static DrawerHandle attach(View drawer, int handleLayout, float verticalOffset) {
if (!(drawer.getParent() instanceof DrawerLayout)) throw new IllegalArgumentException("Argument drawer must be direct child of a DrawerLayout");
return new DrawerHandle((DrawerLayout)drawer.getParent(), drawer, handleLayout, verticalOffset);
}
public static DrawerHandle attach(View drawer, int handleLayout) {
return attach(drawer, handleLayout, 0);
}
@Override
public void onDrawerClosed(View arg0) {
}
@Override
public void onDrawerOpened(View arg0) {
}
@Override
public void onDrawerSlide(View arg0, float slideOffset) {
float translationX = getTranslation(slideOffset);
mHandle.setTranslationX(translationX);
}
@Override
public void onDrawerStateChanged(int arg0) {
}
public View getView(){
return mHandle;
}
public View getDrawer() {
return mDrawer;
}
public void setVerticalOffset(float offset) {
updateScreenDimensions();
mVerticalOffset = offset;
mHandle.setY(mVerticalOffset*mScreenDimensions.y);
}
}
仍然无法获得所需的输出::
到目前为止我做了什么::
MainActivity ::
import java.util.Locale;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.SearchManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
mPlanetTitles = getResources().getStringArray(R.array.planets_array);
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's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// 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
mDrawerToggle = new ActionBarDrawerToggle(this, // host Activity
mDrawerLayout, // DrawerLayout object
R.drawable.ic_drawer, // nav drawer image to replace 'Up' caret
R.string.drawer_open, // "open drawer" description for
// accessibility
R.string.drawer_close // "close drawer" description for
// accessibility
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
float verticalOffset = 0.2f;
View drawer = findViewById(R.id.content_frame);
DrawerHandle.attach(drawer, R.layout.handle, verticalOffset);
if (savedInstanceState == null) {
selectItem(0);
}
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
Fragment fragment = new PlanetFragment();
Bundle args = new Bundle();
args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
activity_main.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" >
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>
到目前为止我得到了什么::
现在,当我点击抽屉把手图标时,我收到以下错误...
Logcat ::
java.lang.IllegalArgumentException: View android.widget.FrameLayout{5282c560 V.E..... ........ 0,0-768,1038 #7f09003d app:id/content_frame} is not a drawer
at android.support.v4.widget.DrawerLayout.isDrawerOpen(DrawerLayout.java:1157)
at android.support.v4.widget.DrawerLayout.isDrawerOpen(DrawerLayout.java:1174)
at learn2crack.slidingnavigationdrawer.DrawerHandle$1.onClick(DrawerHandle.java:81)
at android.view.View.performClick(View.java:4438)
at learn2crack.slidingnavigationdrawer.DrawerHandle$2.onTouch(DrawerHandle.java:99)
请告诉我你宝贵的建议。
任何链接/指导都会有所帮助....
提前致谢...
答案 0 :(得分:1)
您需要将Drawer和其他UI代码放在DrawerLayout中。 考虑这个例子:
<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" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.fscz.views.BounceViewPager
android:id="@+id/content_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
/>
<com.fscz.views.CirclePageIndicator
android:id="@+id/content_indicator"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="10dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginTop="100dp"
style="@style/link"
/>
</RelativeLayout>
<LinearLayout
android:id="@+id/drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:orientation="vertical"
android:padding="20dp"
android:background="@color/black_transparent"
>
<TextView
android:layout_width="240dp"
android:layout_height="wrap_content"
style="@style/text"
android:text="@string/collections"
android:paddingBottom="20dp"
/>
<ListView
android:id="@+id/drawer_list"
android:layout_width="240dp"
android:layout_height="0dip"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:layout_weight="1"
/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
根元素是android.support.v4.widget.DrawerLayout。 里面有2个元素。 RelativeLayout和LinearLayout。 按照惯例,DrawerLayout假定第一个元素是 你的活动/片段/其他的实际布局。第二个元素是抽屉。不是抽屉把手,而是从侧面拖入的UI。您可以通过Java代码添加句柄。
所以......简而言之。您尝试将句柄添加到布局 - 在我的情况下是一个RelativeLayout,在您的情况下是FrameLayout - 而不是抽屉。在您的示例中,抽屉具有id:left_drawer
答案 1 :(得分:-1)
在DrawerHandle类中的onClick中尝试这个
if (mDrawerlayout.isDrawerOpen(Gravity.START)) {
mDrawerlayout.closeDrawers();
} else {
mDrawerlayout.openDrawer(Gravity.START);
}