我是android的初学者并实现我的第一个应用程序!
我在我的应用程序中使用片段导航抽屉,我希望它从右到左打开。在主xml文件的fragment标签中,我设置了android:layout_gravity="right"
,但是当我运行我的应用程序并触摸切换按钮打开导航抽屉时,应用程序突然崩溃了!我从logcat收到java.lang.IllegalArgumentException: No drawer view found with gravity LEFT
的错误。我该怎么做才能解决这个问题?
非常感谢。
// NavDrawerItem.java
public class NavDrawerItem {
private boolean showNotify;
private String title;
public NavDrawerItem() {
}
public NavDrawerItem(boolean showNotify, String title) {
this.showNotify = showNotify;
this.title = title;
}
public boolean isShowNotify() {
return showNotify;
}
public void setShowNotify(boolean showNotify) {
this.showNotify = showNotify;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
nav_drawer_row.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true">
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textSize="15dp"
android:textStyle="bold" />
</RelativeLayout>
fragment_navigation_drawer.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
android:background="@android:color/white">
<RelativeLayout
android:id="@+id/nav_header_container"
android:layout_width="match_parent"
android:layout_height="140dp"
android:layout_alignParentTop="true"
android:background="@color/colorPrimary">
<ImageView
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/ic_user"
android:scaleType="fitCenter"
android:layout_centerInParent="true" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/nav_header_container"
android:layout_marginTop="15dp" />
</RelativeLayout>
NavigationDrawerAdapter.java:
public class NavigationDrawerAdapter extends RecyclerView.Adapter<NavigationDrawerAdapter.MyViewHolder> {
List<NavDrawerItem> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
public NavigationDrawerAdapter(Context context, List<NavDrawerItem> data) {
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
}
public void delete(int position) {
data.remove(position);
notifyItemRemoved(position);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.nav_drawer_row, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
public MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
}
}
}
FragmentDrawer.java:
public class FragmentDrawer extends Fragment {
private static String TAG = FragmentDrawer.class.getSimpleName();
private RecyclerView recyclerView;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private NavigationDrawerAdapter adapter;
private View containerView;
private static String[] titles = null;
private FragmentDrawerListener drawerListener;
public FragmentDrawer() {
}
public void setDrawerListener(FragmentDrawerListener listener) {
this.drawerListener = listener;
}
public static List<NavDrawerItem> getData() {
List<NavDrawerItem> data = new ArrayList<>();
// preparing navigation drawer items
for (int i = 0; i < titles.length; i++) {
NavDrawerItem navItem = new NavDrawerItem();
navItem.setTitle(titles[i]);
data.add(navItem);
}
return data;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// drawer labels
titles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating view layout
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new NavigationDrawerAdapter(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
drawerListener.onDrawerItemSelected(view, position);
mDrawerLayout.closeDrawer(containerView);
}
@Override
public void onLongClick(View view, int position) {
}
}));
return layout;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
toolbar.setAlpha(1 - slideOffset / 2);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
@Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static interface ClickListener {
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
public interface FragmentDrawerListener {
public void onDrawerItemSelected(View view, int position);
}
}
activity_main.xml中:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
</LinearLayout>
<FrameLayout
android:id="@+id/container_body"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<fragment
android:id="@+id/fragment_navigation_drawer"
android:name="com.example.videolabpc.mytoolbar.FragmentDrawer"
android:layout_width="@dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
tools:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
MainActivity.java:
private FragmentDrawer drawerFragment;
drawerFragment = (FragmentDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
drawerFragment.setDrawerListener(this);
崩溃后的Logcat:
09-14 04:24:46.193 1539-1539/? E/SensorManager: sensor or listener is null
09-14 04:24:46.194 1539-1539/? E/SensorManager: registerListenerImpl() [Sensor: null, SensorEventListener: com.lge.lockscreen.model.ScreenTurnOffBySensor@5997807] by com.lge.lockscreen.model.ScreenTurnOffBySensor.registerProximitySensor():58
09-14 04:24:46.203 278-2219/? E/lge_audio_pcm_dump: lge_set_dump_config: exit dump_config : 0
09-14 04:24:48.544 278-1070/? E/audio_hw_primary: select_devices: enter and usecase(1)
09-14 04:24:48.545 278-1070/? E/audio_hw_primary: enable_snd_device: enter 2
09-14 04:24:51.913 278-1325/? E/audio_hw_primary: disable_snd_device: enter 2
09-14 04:25:14.826 5149-5149/com.teroject.teroject E/GMPM: GoogleService failed to initialize, status: 10, Missing an expected resource: 'R.string.google_app_id' for initializing Google services. Possible causes are missing google-services.json or com.google.gms.google-services gradle plugin.
09-14 04:25:14.826 5149-5149/com.teroject.teroject E/GMPM: Scheduler not set. Not logging error/warn.
09-14 04:25:14.881 5149-5181/com.teroject.teroject E/GMPM: Uploading is not possible. App measurement disabled
09-14 04:25:15.600 5149-5149/com.teroject.teroject E/OneSignal: You must initialize OneSignal before modifying tags! Omitting this tag operation.
09-14 04:25:16.658 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10004
09-14 04:25:16.860 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10187
09-14 04:25:16.901 5149-5149/com.teroject.teroject E/MediaProfilesEx-JNI: register_com_lge_media_MediaProfilesEx
09-14 04:25:16.903 5149-5149/com.teroject.teroject E/MediaRecorderEx-JNI: register_com_lge_media_MediaRecorderEx
09-14 04:25:16.905 5149-5149/com.teroject.teroject E/SurfaceControlEx: register_com_lge_view_SurfaceControlEx
09-14 04:25:16.912 5149-5149/com.teroject.teroject E/MediaPlayerEx-jni: register_com_lge_view_MediaPlayerEx
09-14 04:25:21.548 5149-5149/com.teroject.teroject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.teroject.teroject, PID: 5149
java.lang.IllegalArgumentException: No drawer view found with gravity LEFT
at android.support.v4.widget.DrawerLayout.openDrawer(DrawerLayout.java:1618)
at android.support.v7.app.ActionBarDrawerToggle.toggle(ActionBarDrawerToggle.java:290)
at android.support.v7.app.ActionBarDrawerToggle.access$100(ActionBarDrawerToggle.java:64)
at android.support.v7.app.ActionBarDrawerToggle$1.onClick(ActionBarDrawerToggle.java:200)
at android.view.View.performClick(View.java:4764)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5354)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
09-14 04:25:21.579 278-1070/? E/audio_hw_primary: select_devices: enter and usecase(1)
09-14 04:25:21.579 278-1070/? E/audio_hw_primary: enable_snd_device: enter 2
09-14 04:25:21.766 1001-1483/? E/ConnectivityService: RemoteException caught trying to send a callback msg for NetworkRequest [ id=8, legacyType=-1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN] ]
09-14 04:25:22.510 2648-2648/? E/NetworkScheduler.SR: Invalid parameter app
09-14 04:25:22.510 2648-2648/? E/NetworkScheduler.SR: Invalid package name : Perhaps you didn't include a PendingIntent in the extras?
09-14 04:25:22.562 3927-4157/? E/Drive.UninstallOperation: Package still installed com.teroject.teroject
09-14 04:25:22.730 5547-5547/? E/Finsky: [1] com.google.android.finsky.wear.bo.a(838): onConnectionFailed: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}
09-14 04:25:23.217 3927-5659/? E/IntentOperationSvc: Failed to instantiate Chimera operation impl, dropping operation
09-14 04:25:23.223 5547-5547/? E/Finsky: [1] com.google.android.finsky.wear.bo.a(838): onConnectionFailed: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}
09-14 04:25:24.332 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10187
09-14 04:25:24.585 2648-2648/? E/NetworkScheduler.SR: Invalid parameter app
09-14 04:25:24.585 2648-2648/? E/NetworkScheduler.SR: Invalid package name : Perhaps you didn't include a PendingIntent in the extras?
09-14 04:25:24.776 278-1325/? E/audio_hw_primary: disable_snd_device: enter 2
09-14 04:25:24.799 5860-5860/? E/App: [App][onCreate()] 4.40.21
09-14 04:25:26.507 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10101
09-14 04:25:27.341 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10100
09-14 04:25:29.554 5901-5936/? E/a: Failed to send crash attachment report /data/data/com.instagram.android/app_minidumps/307ff5ad80207d193ff0aa19e8633a8a.dmp
com.facebook.g.b.c: Error while sending report to Http Post Form.
at com.facebook.g.b.d.a(HttpPostSender.java:110)
at com.facebook.g.n.b(ErrorReporter.java:1436)
at com.facebook.g.n.a(ErrorReporter.java:1626)
at com.facebook.g.n.a(ErrorReporter.java:1483)
at com.facebook.g.n.a(ErrorReporter.java:118)
at com.facebook.g.i.a(ErrorReporter.java:348)
at com.facebook.g.i.run(ErrorReporter.java:360)
Caused by: java.net.SocketTimeoutException: failed to connect to www.facebook.com/10.10.34.36 (port 443) after 3000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:169)
at libcore.io.IoBridge.connect(IoBridge.java:122)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
at java.net.Socket.connect(Socket.java:886)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:139)
at com.android.okhttp.Connection.connect(Connection.java:155)
at com.android.okhttp.Connection.connect(Connection.java:170)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:309)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:242)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:397)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:118)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:229)
at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:25)
at com.facebook.g.c.f.a(HttpRequest.java:52)
at com.facebook.g.b.d.b(HttpPostSender.java:134)
at com.facebook.g.b.d.a(HttpPostSender.java:108)
at com.facebook.g.n.b(ErrorReporter.java:1436)
at com.facebook.g.n.a(ErrorReporter.java:1626)
at com.facebook.g.n.a(ErrorReporter.java:1483)
at com.facebook.g.n.a(ErrorReporter.java:118)
at com.facebook.g.i.a(ErrorReporter.java:348)
at com.facebook.g.i.run(ErrorReporter.java:360)
09-14 04:25:32.298 5901-5901/? E/ActivityThread: Failed to find provider info for com.facebook.katana.provider.AttributionIdProvider
09-14 04:25:32.311 5901-5954/? E/ActivityThread: Failed to find provider info for com.facebook.katana.provider.AttributionIdProvider
09-14 04:25:32.446 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10101
09-14 04:25:32.727 272-994/? E/BandwidthController: [LG DATA] No such appUid: 10101
答案 0 :(得分:1)
问题是ActionBarDrawerToggle
总是希望抽屉位于与Gravity.START
对应的一侧。在大多数区域设置中,这是在左侧,因此它尝试使用Gravity.LEFT
打开抽屉,但是您的是在另一侧,因此它会抛出异常。无论这看起来像是一个聪明的设计决定,它就是它的本质。
如果您遵循材料设计准则,您的抽屉将在操作栏打开时覆盖它(可能已经在执行此操作)。特别是出于这个原因,我不喜欢使用ActionBarDrawerToggle
并且没有发现它特别有用;菜单图标到箭头的动画被抽屉遮挡,其他功能很容易直接在活动中实现。在您的情况下,如果您的另一侧的抽屉没有覆盖图标,动画可能实际上很有用,但是您可能根本不想让图标完全动画。
在onCreate()
方法中,您需要做的只是
toolbar.setNavigationOnClickListener()
(或在OnClickListener
的视图上设置Toolbar
)并让此听众使用drawerLayout.openDrawer(Gravity.RIGHT)
和等效的closeDrawer()
切换抽屉方法drawerLayout.addDrawerListener()
添加侦听器。当抽屉打开或关闭时,您可以使用此监听器来更改工具栏的图标和/或其内容描述(用于辅助功能),或者做任何您喜欢的事情答案 1 :(得分:0)
我添加以下属性:
android:layoutDirection="rtl"
到DrawerLayout和NavigationView解决了问题