美文网首页
copy微信头(toolbar)

copy微信头(toolbar)

作者: 那个唐僧 | 来源:发表于2017-03-19 20:35 被阅读111次

    类似于微信的和UC的左边向右边滑动,finish掉activity.人IOS自带这个功能..握了个草
    然后封装一个统一的带左边返回键的activity(封装toolbar)


    a.gif

    这个肯定是MD风格的toolbar.所以先依赖包

    compile 'com.android.support:appcompat-v7:25.3.0'
    

    既然要封装,那就是要抽取个爸爸呗.那就抽吧..

    public abstract class BaseActivity extends SlidingActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(getLayout());
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            TextView title = (TextView) findViewById(R.id.toolbar_title);
            title.setText(setTitleText());
            setSupportActionBar(toolbar);
            //去掉默认显示的标题
            getSupportActionBar().setDisplayShowTitleEnabled(false);
            if (getSupportActionBar() != null) {
                //设置返回的按钮
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            }
            eventAndData();
        }
        /**
         * 根据返回的字符来设置Activity的title
         *
         * @return
         */
        protected abstract String setTitleText();
        /**
         * 处理事件和数据
         */
        protected abstract void eventAndData();
        /**
         * 返回子类的布局
         *
         * @return
         */
        protected abstract int getLayout();
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                //监听返回的按钮
                case android.R.id.home:
                    finish();
                    return true;
                //右边more按钮的点击事件.如需要,子类去实现
    //            case R.id.more:
    //                Toast.makeText(BaseActivity.this, "点击了菜单", Toast.LENGTH_SHORT).show();
    //                return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            //显示右边more按钮
    //        getMenuInflater().inflate(R.menu.more, menu);//加载menu文件到布局
            return true;
        }
    }
    

    注释写的比较少,但是应该还算清楚吧..
    上面抽取的baseactivity中继承的是SlidingActivity,这个是用来向右边滑动finish的,代码如下

    public class SlidingActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            SlidingLayout rootView = new SlidingLayout(this);
            rootView.bindActivity(this);
        }
    
        @Override
        public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
            super.startActivityForResult(intent, requestCode, options);
            overridePendingTransition(R.anim.anim_enter, R.anim.anim_exit);
        }
    
        @Override
        public void finish() {
            super.finish();
            overridePendingTransition(R.anim.anim_enter, R.anim.anim_exit);
        }
    }
    

    然后发现了SlidingLayout,这个是封装的自定义layout

    public class SlidingLayout extends FrameLayout {
        private Activity mActivity;
        private Scroller mScroller;
        /**
         * 上次ACTION_MOVE时的X坐标
         */
        private int mLastMotionX;
        /**
         * 屏幕宽度
         */
        private int mWidth = -1;
        /**
         * 可滑动的最小X坐标,小于该坐标的滑动不处理
         */
        private int mMinX;
        /**
         * 页面边缘的阴影图
         */
        private Drawable mLeftShadow;
        /**
         * 页面边缘阴影的宽度默认值
         */
        private static final int SHADOW_WIDTH = 16;
        /**
         * 页面边缘阴影的宽度
         */
        private int mShadowWidth;
    
        public SlidingLayout(Activity activity) {
            this(activity, null);
        }
    
        public SlidingLayout(Activity activity, AttributeSet attrs) {
            this(activity, attrs, 0);
        }
    
        public SlidingLayout(Activity activity, AttributeSet attrs, int defStyleAttr) {
            super(activity, attrs, defStyleAttr);
            initView(activity);
        }
    
        private void initView(Activity activity) {
            mActivity = activity;
            mScroller = new Scroller(mActivity);
            mLeftShadow = getResources().getDrawable(R.drawable.left_shadow);
            int density = (int) activity.getResources().getDisplayMetrics().density;
            mShadowWidth = SHADOW_WIDTH * density;
        }
    
        /**
         * 绑定Activity
         */
        public void bindActivity(Activity activity) {
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            View child = decorView.getChildAt(0);
            decorView.removeView(child);
            addView(child);
            decorView.addView(this);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mLastMotionX = (int) event.getX();
                    mWidth = getWidth();
                    mMinX = mWidth / 10;
                    break;
                case MotionEvent.ACTION_MOVE:
                    int rightMovedX = mLastMotionX - (int) event.getX();
                    if (getScrollX() + rightMovedX >= 0) {// 左侧即将滑出屏幕
                        scrollTo(0, 0);
                    } else if ((int) event.getX() > mMinX) {// 手指处于屏幕边缘时不处理滑动
                        scrollBy(rightMovedX, 0);
                    }
                    mLastMotionX = (int) event.getX();
                    break;
                case MotionEvent.ACTION_UP:
                    if (-getScrollX() < mWidth / 2) {
                        scrollBack();
                    } else {
                        scrollClose();
                    }
                    break;
            }
            return true;
        }
    
        /**
         * 滑动返回
         */
        private void scrollBack() {
            int startX = getScrollX();
            int dx = -getScrollX();
            mScroller.startScroll(startX, 0, dx, 0, 300);
            invalidate();
        }
    
        /**
         * 滑动关闭
         */
        private void scrollClose() {
            int startX = getScrollX();
            int dx = -getScrollX() - mWidth;
            mScroller.startScroll(startX, 0, dx, 0, 300);
            invalidate();
        }
    
        @Override
        public void computeScroll() {
            if (mScroller.computeScrollOffset()) {
                scrollTo(mScroller.getCurrX(), 0);
                postInvalidate();
            } else if (-getScrollX() == mWidth) {
                mActivity.finish();
            }
            super.computeScroll();
        }
    
        @Override
        protected void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(canvas);
            drawShadow(canvas);
        }
    
        /**
         * 绘制边缘的阴影
         */
        private void drawShadow(Canvas canvas) {
            // 保存画布当前的状态
            canvas.save();
            // 设置drawable的大小范围
            mLeftShadow.setBounds(0, 0, mShadowWidth, getHeight());
            // 让画布平移一定距离
            canvas.translate(-mShadowWidth, 0);
            // 绘制Drawable
            mLeftShadow.draw(canvas);
            // 恢复画布的状态
            canvas.restore();
        }
    }
    

    滑动时的动画

    <translate
            android:duration="300"
            android:fromXDelta="100%p"
            android:toXDelta="0" />
    <translate
            android:duration="300"
            android:fromXDelta="0"
            android:toXDelta="100%p" />
    

    滑动时的阴影

    android:shape="rectangle">
        <!--颜色渐变范围-->
        <gradient
            android:endColor="#50000000"
            android:startColor="#00000000" />
    

    toolbar的封装

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:singleLine="true"
            android:textColor="#fff"
            android:textSize="20sp" />
    </android.support.v7.widget.Toolbar>
    

    主题

    <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="android:textColorPrimary">#fff</item>
            <item name="colorAccent">@color/colorAccent</item>
            <!-- Toolbar Theme / Apply white arrow -->
            <item name="colorControlNormal">@android:color/white</item>
            <!--Navigation icon颜色设置-->
            <item name="drawerArrowStyle">@style/AppTheme.MyDrawerArrowStyle</item>
            <!--设置右边三点的颜色-->
            <item name="android:windowBackground">@android:color/transparent</item>
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:windowAnimationStyle">@android:style/Animation</item>
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
        </style>
    
        <!--加入一個新的 navigation drarwer 的風格-->
        <style name="AppTheme.MyDrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
            <!--將 spinBars 屬性設定為 false-->
            <item name="spinBars">false</item>
            <!--設定 drawer arrow 的顏色-->
            <item name="color">@android:color/white</item>
        </style>
    

    mainActivity布局

    <include layout="@layout/backtoolbar"/>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="跳"
            android:onClick="jump"
            android:textColor="@color/colorAccent"
            />
    

    mainActivity代码

    @Override
        protected String setTitleText() {
            return "今日事今日毕";
        }
        @Override
        protected void eventAndData() {
    
        }
        @Override
        protected int getLayout() {
            return R.layout.activity_main;
        }
        public void jump(View view) {
            startActivity(new Intent(this, Main2Activity.class));
        }
    

    大致就这么多代码.需要写类似于这样的activity的话,只需要直接继承baseActivity即可,然后则需要在子类的布局中include刚才的toolbar布局就好.既可以向右滑动返回,也可以点击返回按钮返回.
    另外如果需要在toolbar的右边添加menu的话,子类只需要重写onCreateOptionsMenu方法和onOptionsItemSelected即可,上文代码中注释掉的代码即为menu的点击事件.

    b.gif

    相关文章

      网友评论

          本文标题:copy微信头(toolbar)

          本文链接:https://www.haomeiwen.com/subject/vsdvnttx.html