抽屉控件在移动端开发中是一个常见的交互组件,它可以用来实现多种不同效果的界面交互,例如显示和隐藏菜单、导航栏等,在此基础上,Android平台提供了上下抽屉控件更加灵活的界面展示和操作方式。下面将从多个方面对Android平台上下抽屉控件进行详细阐述,通过实现代码来展示其优雅的使用方法。
一、基本使用
上下抽屉控件( DrawerLayout )是 Android 平台提供的继承自 ViewGroup 的控件,它可以在屏幕上使用不重叠的方式将内容滑入或滑出。通过添加子元素,可以把两个子元素分别放到上下两侧。下面是简单的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"> <LinearLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <ListView android:id="@+id/drawer" android:layout_width="240dp" android:layout_height="match_parent"> </ListView> </android.support.v4.widget.DrawerLayout>
上述代码中, DrawerLayout 作为根布局对应整个屏幕,内部通过添加两个子元素,实现内容抽屉的展开和收起操作。第一个子元素是开发者自己的布局,它在默认情况下充满整个屏幕。第二个子元素是抽屉的内容布局,它通常是一个ListView或者其他的视图控件。
通过以下代码初始化DrawerLayout:
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); ListView drawerList = (ListView) findViewById(R.id.drawer);
接下来,为DrawerLayout设置抽屉内容布局:
drawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() { @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); } @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); } });
上述代码中,我们只是简单的将DrawerLayout设置监听器,然后在抽屉打开和关闭时,分别触发相应的事件。需要注意的是,在onDrawerClosed和onDrawerOpened中,应该分别处理您自己的逻辑,以实现相应的ui效果。
二、手势操作
与常规的上下抽屉控件不同, Android 平台提供了一些高级功能,例如手势操作。这些操作可以用来更好地处理视图控件之间的交互。您可以使用GestureDetector实现以下两个手势操作。
一、使用下拉手势即可打开抽屉控件。下面是实现这一手势操作的代码:
mGestureDetector = new GestureDetectorCompat(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent event) { return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(velocityY) > Math.abs(velocityX)) { if (velocityY > 0) { mDrawerLayout.closeDrawer(mDrawerList); } else { mDrawerLayout.openDrawer(mDrawerList); } return true; } return false; } });
上述代码中,我们首先创建一个GestureDetector对象,然后通过监听onDown和onFling事件,实现了手势操作的打开和关闭抽屉控件。
二、使用滑动手势也可以打开和关闭抽屉控件。滑动手势直接与系统的默认返回操作保持一致,在用户滑动过程中,即打开或关闭抽屉控件。下面是相应的代码:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); mDrawerLayout.setScrimColor(Color.TRANSPARENT); mDrawerLayout.openDrawer(GravityCompat.START); mDrawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() { @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); if (slideOffset >= 0f && slideOffset <= 1f) { ViewCompat.setTranslationX(contentFrame, drawerView.getWidth() * slideOffset); ViewCompat.setAlpha(drawerView, 0.6f + 0.4f * (1.0f - slideOffset)); } } @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, GravityCompat.START); } });
上述代码中,我们首先将抽屉控件解锁并设置颜色透明,然后使用GravityCompat.START打开抽屉控件。最后在DrawerLayout.SimpleDrawerListener中使用onDrawerSlide实现滑动手势的打开和关闭抽屉控件。
三、效果展示
最后,我们来演示一个更高级的抽屉控件界面效果,它包含主界面和一个隐藏式的抽屉效果。主界面还可以对抽屉内的列表项进行左右滑动删除的交互。下面是完整示例代码:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private DrawerLayout mDrawerLayout; private ListView mDrawerList; private View contentFrame; private ActionBarDrawerToggle mDrawerToggle; private CharSequence mDrawerTitle; private CharSequence mTitle; private ArrayListmPlanetTitles = new ArrayList (); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTitle = mDrawerTitle = getTitle(); mPlanetTitles.add("Mercury"); mPlanetTitles.add("Venus"); mPlanetTitles.add("Earth"); mPlanetTitles.add("Mars"); mPlanetTitles.add("Jupiter"); mPlanetTitles.add("Saturn"); mPlanetTitles.add("Uranus"); mPlanetTitles.add("Neptune"); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer); contentFrame = findViewById(R.id.content_frame); mDrawerList.setAdapter(new ArrayAdapter (this, R.layout.drawer_list_item, mPlanetTitles)); mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) { public void onDrawerClosed(View view) { super.onDrawerClosed(view); getSupportActionBar().setTitle(mTitle); invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getSupportActionBar().setTitle(mDrawerTitle); invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); if (savedInstanceState == null) { selectItem(0); } } 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) { 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(); mDrawerList.setItemChecked(position, true); mDrawerLayout.closeDrawer(mDrawerList); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } public static class PlanetFragment extends Fragment { public static final String ARG_PLANET_NUMBER = "planet_number"; public PlanetFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { int i = getArguments().getInt(ARG_PLANET_NUMBER); String planet = getResources().getStringArray(R.array.planets_array)[i]; int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()), "drawable", getActivity().getPackageName()); View rootView = inflater.inflate(R.layout.fragment_planet, container, false); ImageView imageView = (ImageView) rootView.findViewById(R.id.image); TextView textView = (TextView) rootView.findViewById(R.id.text); imageView.setImageResource(imageId); textView.setText(planet); return rootView; } } }
上述代码中,类型属性有 DrawerLayout 和 ListView 。这个页面中的DrawerLayout控制了左侧的抽屉,ListView 就是左侧抽屉中的元素。ListView 的项目被点击时会调用 selectItem 方法,它通过 Fragment 的替换方法来更新主区域域的显示。
为了进一步改进用户体验,我们还对主界面的列表项进行了左右滑动删除等交互操作,代码如下:
mListView = (SwipeMenuListView) findViewById(R.id.listView); ... SwipeMenuCreator creator = new SwipeMenuCreator() { @Override public void create(SwipeMenu menu) { SwipeMenuItem deleteItem = new SwipeMenuItem( getApplicationContext()); deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9, 0x3F, 0x25))); deleteItem.setWidth(dp2px(90)); deleteItem.setIcon(R.drawable.ic_delete); menu.addMenuItem(deleteItem); } }; mListView.setMenuCreator(creator); mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
上述代码中,我们使用了 SwipeMenuListView 组件实现主界面的滑动删除操作,在create方法中将删除选项添加到了滑动操作中,改进了用户的交互效果。
四、结语
上述示例代码介绍了一些常见、高级的Android上下抽屉控件操作,通过这些操作及对其效果细致的介绍,可以让开发者更好地了解使用上下抽屉控件。希望本文对您的移动应用开发有所帮助。