首页 > 编程知识 正文

Android 上下抽屉控件

时间:2023-11-21 05:09:33 阅读:293042 作者:JVQU

抽屉控件在移动端开发中是一个常见的交互组件,它可以用来实现多种不同效果的界面交互,例如显示和隐藏菜单、导航栏等,在此基础上,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 ArrayList mPlanetTitles = 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上下抽屉控件操作,通过这些操作及对其效果细致的介绍,可以让开发者更好地了解使用上下抽屉控件。希望本文对您的移动应用开发有所帮助。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。