一款基于Material Desgin设计的APP

原创 2016年01月01日 14:39:41

源码小编已经上传到github上了,求star啊
https://github.com/Hankkin/TaoSchool

前言

好久没写博客了,小编最近在研究Material Desgin(以下简称MD),话说现在市场的上App好多都用上了MD,先简单的介绍以下MD吧,它到底是个什么东东啊?
看看官方文档吧(中文版的呦)
http://wiki.jikexueyuan.com/project/material-design/
官方解释说叫:原质化设计
小编也不懂什么叫原质化设计,我的理解就是遵循着用户体验的效果实现着一些让用户用起来舒适满意的动画效果及设计。怎么样这个够形象了吧,不看效果炫不炫,只看用户用着你的APP满意不满意。大体就是这样,就这样,小编追赶着时代的潮流也设计了一个属于自己的APP。它叫淘School(也可以叫它“淘学”哦)。
下载地址:
二维码:
这里写图片描述
网站:
http://hankkin.bmob.cn
PRE:
http://pre.im/x9nH
360开发者平台:
http://zhushou.360.cn/detail/index/soft_id/3181637?recrefer=SE_D_%E6%B7%98School
百度开发平台
http://shouji.baidu.com/soft/item?docid=8561791&from=&f=search_app_淘School%40list_1_title%401%40header_all_input
看一下效果吧:
这里写图片描述

介绍

淘School是一款基于MD的一款校园二手商品交易平台,当然小编只是简单的开发了一些功能,并没有完善,只是想做一款MD的APP,并没有交易支付的功能,只是把我感觉比较好的MD的一些组件融到了项目中,下面小编来详细介绍一下用到的技术:
因为小编服务器端不是很熟练,所以就用了Bmob,还不错挺容易上手的,就依赖了它的两个库而已,网络请求和模型都是封装好的,我们直接调用就可以。
先看一下小编引用的一些库吧:

compile 'com.android.support:appcompat-v7:23.1.0'
    compile files('libs/BmobSDK_V3.4.5_1111.jar')
    compile files('libs/okio-1.4.0.jar')
    compile 'com.android.support:support-v4:23.1.0'
    compile 'com.github.manuelpeinado.fadingactionbar:fadingactionbar-abc:3.1.2'
    compile 'com.android.support:design:23.1.0'
    compile 'com.pnikosis:materialish-progress:1.7'
    compile 'me.drakeet.materialdialog:library:1.2.8'
    compile 'com.jakewharton:butterknife:7.0.1'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
    compile 'com.weiwangcn.betterspinner:library:1.1.0'
    compile 'com.nineoldandroids:library:2.4.0'

1.Android Support Desgin

CollapsingAvatarToolbar 头像随ListView滚动缩回到ActionBar特效
TextInputLayout带动画的输入框

2.ActionBarDrawerToggle、DrawerLayout、ActionBar 结合

3.RippleEffect水波纹效果

4.PagerSlidingTabStrip+viewpager实现选项卡左右滑动

5.FloatActiconButton悬浮按钮实现仿钉钉悬浮按钮

6.PullToZoomScrollView实现下拉自动放大头部View

7.materialdialog实现的对话框

8.MaterialSpinner实现的带效果的spinner

9.butterknife注解框架

小编用到的技术基本上就这些,下面小编会详细的介绍一下。

技术实现

1.主界面

先介绍一下主界面吧,主界面小编用的是ActionBarDrawerToggle+DrawerLayout+ActionBar实现的滑动抽屉效果。布局文件就不介绍了,这个用的也挺多的,网上资料也很多,介绍几个方法吧

//设定左上角突变可点击
        getSupportActionBar().setHomeButtonEnabled(true);   
        // 给左上角图标的左边加上一个返回的图标 。对应ActionBar.DISPLAY_HOME_AS_UP
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);  
        //设置标题 getSupportActionBar().setTitle(getResources().getString(R.string.action_title));
         // 使自定义的普通View能在title栏显示,即actionBar.setCustomView能起作用,对应ActionBar.DISPLAY_SHOW_CUSTOM
        actionBar.setDisplayShowCustomEnabled(true) 
closeDrawers();//关闭抽屉

2.滑动选项卡

小编主界面的滑动选项卡用的是PagerSlidingTabStrip+viewpager管理fragment,详细用法大家可以看一下小编的这边博客:Android源码解析-仿今日头条PagerSlidingTabStrip滑动页面导航效果不详细介绍了。

3.主界面的悬浮按钮

悬浮按钮在github上有Demo,
https://github.com/futuresimple/android-floating-action-button
https://github.com/makovkastar/FloatingActionButton
小编用的是第一个,然后重写了一下里面的滑动监听实现了listview滑动显示隐藏按钮。看一下布局文件:

<com.hankkin.compustrading.view.floatbutton.FloatingActionsMenu
        android:id="@+id/multiple_actions"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        fab:fab_addButtonColorNormal="@color/origle"
        fab:fab_addButtonColorPressed="@color/origle_tab"
        fab:fab_addButtonPlusIconColor="@color/white"
        fab:fab_labelStyle="@style/menu_labels_style"
        android:layout_marginBottom="@dimen/smaller_space"
        android:layout_marginRight="@dimen/smaller_space"
        android:layout_marginEnd="@dimen/smaller_space">

        <com.hankkin.compustrading.view.floatbutton.FloatingActionButton
            android:id="@+id/fb_update"
            android:src="@drawable/update"
            fab:fab_labelStyle="@style/menu_labels_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_colorNormal="@color/theme_color"
            fab:fab_colorPressed="@color/theme_color_tab"/>

        <com.hankkin.compustrading.view.floatbutton.FloatingActionButton
            android:id="@+id/fb_new"
            fab:paddingEnd="@dimen/small_space"
            android:src="@drawable/edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_colorNormal="@color/theme_color"
            fab:fab_colorPressed="@color/theme_color_tab"/>
        <com.hankkin.compustrading.view.floatbutton.FloatingActionButton
            android:id="@+id/fb_person"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/title_person"
            fab:fab_colorNormal="@color/theme_color"
            fab:fab_colorPressed="@color/theme_color_tab"/>

    </com.hankkin.compustrading.view.floatbutton.FloatingActionsMenu>

下面是重写的ListView滑动监听实现显示隐藏悬浮按钮

public void attachToListView(@NonNull AbsListView listView,
                               ScrollDirectionListener scrollDirectionListener,
                               AbsListView.OnScrollListener onScrollListener) {
    AbsListViewScrollDetectorImpl scrollDetector = new AbsListViewScrollDetectorImpl();
    scrollDetector.setScrollDirectionListener(scrollDirectionListener);
    scrollDetector.setOnScrollListener(onScrollListener);
    scrollDetector.setListView(listView);
    scrollDetector.setScrollThreshold(mScrollThreshold);
    listView.setOnScrollListener(scrollDetector);
  }

  private class AbsListViewScrollDetectorImpl extends AbsListViewScrollDetector {
    private ScrollDirectionListener mScrollDirectionListener;
    private AbsListView.OnScrollListener mOnScrollListener;

    private void setScrollDirectionListener(ScrollDirectionListener scrollDirectionListener) {
      mScrollDirectionListener = scrollDirectionListener;
    }

    public void setOnScrollListener(AbsListView.OnScrollListener onScrollListener) {
      mOnScrollListener = onScrollListener;
    }

    @Override
    public void onScrollDown() {
      show();
      if (mScrollDirectionListener != null) {
        mScrollDirectionListener.onScrollDown();
      }
    }

    @Override
    public void onScrollUp() {
      hide();
      if (mScrollDirectionListener != null) {
        mScrollDirectionListener.onScrollUp();
      }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                         int totalItemCount) {
      if (mOnScrollListener != null) {
        mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
      }

      super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
      if (mOnScrollListener != null) {
        mOnScrollListener.onScrollStateChanged(view, scrollState);
      }

      super.onScrollStateChanged(view, scrollState);
    }
  }
  public void show() {
    show(true);
  }

  public void hide() {
    hide(true);
  }
  public void show(boolean animate) {
    toggle(true, animate, false);
  }

  public void hide(boolean animate) {
    toggle(false, animate, false);
  }
  private void toggle(final boolean visible, final boolean animate, boolean force) {
    if (mVisible != visible || force) {
      mVisible = visible;
      int height = getHeight();
      if (height == 0 && !force) {
        ViewTreeObserver vto = getViewTreeObserver();
        if (vto.isAlive()) {
          vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
              ViewTreeObserver currentVto = getViewTreeObserver();
              if (currentVto.isAlive()) {
                currentVto.removeOnPreDrawListener(this);
              }
              toggle(visible, animate, true);
              return true;
            }
          });
          return;
        }
      }
      int translationY = visible ? 0 : height + getMarginBottom();
      if (animate) {
        ViewPropertyAnimator.animate(this).setInterpolator(mInterpolator)
                .setDuration(TRANSLATE_DURATION_MILLIS)
                .translationY(translationY);
      } else {
        ViewHelper.setTranslationY(this, translationY);
      }

      // On pre-Honeycomb a translated view is still clickable, so we need to disable clicks manually
      if (!hasHoneycombApi()) {
        setClickable(visible);
      }
    }
  }
  private int getMarginBottom() {
    int marginBottom = 0;
    final ViewGroup.LayoutParams layoutParams = getLayoutParams();
    if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
      marginBottom = ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin;
    }
    return marginBottom;
  }
  private boolean hasHoneycombApi() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
  }
}

然后再activity中这样用:

fab.attachToListView(lvProduct, new ScrollDirectionListener() {
                @Override
                public void onScrollDown() {
                    Log.d("ListViewFragment", "onScrollDown()");
                }

                @Override
                public void onScrollUp() {
                    Log.d("ListViewFragment", "onScrollUp()");
                }
            }, new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    Log.d("ListViewFragment", "onScrollStateChanged()");
                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    Log.d("ListViewFragment", "onScroll()");
                }
            });

很简单。

4.商品详细界面上下滑动头像回到actionbar上

这个效果是小编一直都想实现的,因为技术、时间、能力有限,所以一直没去搞,在网上搜了好多相关的帖子,博客,终于让我找到一个类似的,做了一下改动实现了。
这个技术是CoordinatorLayout+Toolbar+CollapsingAvatarToolbar实现的。实际上support desgin可以实现文字的上下滑动但是没有头像的上下滑动改变大小。CollapsingAvatarToolbar这个组件实现了这一效果,当然并不是小编写的,只是小编改的,但是能改出来小编也已经很高兴了。给大家看一下布局:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/theme_color"
    android:clipToPadding="true"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout

        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="@color/theme_color"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

            <com.hankkin.compustrading.view.CollapsingAvatarToolbar
                android:id="@+id/stuff_container"
                android:layout_width="wrap_content"
                android:layout_height="?attr/actionBarSize"
                android:orientation="vertical">

                <com.hankkin.compustrading.view.RoundedImageView
                    android:id="@+id/usericon"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center_vertical"
                    android:src="@drawable/defaut" />

                <TextView
                    android:id="@+id/username"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:fontFamily="sans-serif-medium"
                    android:text="Hankkin"
                    android:textColor="@android:color/white"
                    android:textSize="18dp" />

                <!--<LinearLayout android:layout_width="wrap_content"-->
                <!--android:layout_height="wrap_content"-->
                <!--android:layout_gravity="center_vertical"-->
                <!--android:layout_marginLeft="16dp"-->
                <!--android:orientation="vertical">-->

                <!-- -->

                <!--<TextView android:id="@+id/subtitle"-->
                <!--android:layout_width="wrap_content"-->
                <!--android:layout_height="wrap_content"-->
                <!--android:text="Subtitle"-->
                <!--android:textColor="#80ffffff"-->
                <!--android:textSize="15dp" />-->
                <!--</LinearLayout>-->
            </com.hankkin.compustrading.view.CollapsingAvatarToolbar>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/gray"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:padding="@dimen/small_space"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <LinearLayout
                android:gravity="center_vertical"
                android:padding="@dimen/small_space"
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <com.hankkin.compustrading.view.RoundedImageView
                    android:id="@+id/iv_user_head"
                    android:src="@drawable/defaut"
                    android:layout_width="35dp"
                    android:layout_height="35dp" />
                <TextView
                    android:layout_marginLeft="@dimen/small_space"
                    android:textSize="@dimen/normal_textSize"
                    android:text="Hankkin"
                    android:textColor="@color/black"
                    android:layout_weight="1"
                    android:id="@+id/tv_username"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
                <TextView
                    android:textColor="@color/deep_gray"
                    android:textSize="@dimen/small_textSize"
                    android:text="asdas"
                    android:id="@+id/tv_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>

            <TextView
                android:layout_marginLeft="@dimen/small_space"
                android:textColor="@color/black"
                android:textSize="@dimen/normal_textSize"
                android:id="@+id/tv_pro_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="二手" />

            <TextView
                android:layout_marginLeft="@dimen/small_space"
                android:textColor="@color/black"
                android:textSize="@dimen/normal_textSize"
                android:id="@+id/tv_pro_desc"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <ImageView
                android:scaleType="fitXY"
                android:id="@+id/iv_product"
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:background="@color/deep_gray" />
            <LinearLayout
                android:paddingBottom="@dimen/small_space"
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:drawablePadding="@dimen/tiny_space"
                    android:drawableLeft="@drawable/location"
                    android:textSize="@dimen/small_textSize"
                    android:layout_marginTop="@dimen/small_space"
                    android:layout_marginLeft="@dimen/middle_space"
                    android:text="天津理工大学"
                    android:id="@+id/tv_school"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
                <TextView
                    android:textSize="@dimen/small_textSize"
                    android:textColor="@color/theme_color"
                    android:layout_marginRight="@dimen/middle_space"
                    android:layout_marginTop="@dimen/small_space"
                    android:text="¥"
                    android:id="@+id/tv_price"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />

            </LinearLayout>

            <LinearLayout
                android:layout_marginTop="@dimen/middle_space"
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="64dp">

                <LinearLayout
                    android:gravity="center"
                    android:layout_weight="1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
                    <ImageView
                        android:src="@drawable/telephone"
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent" />

                </LinearLayout>
                <LinearLayout
                    android:gravity="center"
                    android:layout_weight="1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
                    <ImageView
                        android:src="@drawable/sms"
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent" />

                </LinearLayout>
                <LinearLayout
                    android:gravity="center"
                    android:layout_weight="1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
                    <ImageView
                        android:src="@drawable/collect"
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent" />

                </LinearLayout>

            </LinearLayout>
        </LinearLayout>



    </android.support.v4.widget.NestedScrollView>


</android.support.design.widget.CoordinatorLayout>

效果就这样:
这里写图片描述

5.个人资料界面

这个界面小编用的是PullToZoomScrollViewEx,github地址
https://github.com/matrixxun/PullToZoomInListView
用法也很简单,我们在布局里面嵌套一个PullToZoomScrollViewEx,而布局的head,content,footer都可以自定义,然后引用进来就可以了。

PullToZoomScrollViewEx scrollView = (PullToZoomScrollViewEx) findViewById(R.id.my_pull_scoll);
        headView = LayoutInflater.from(this).inflate(R.layout.profile_head_view, null, false);
        zoomView = LayoutInflater.from(this).inflate(R.layout.profile_zoom_view, null, false);
        contentView = LayoutInflater.from(this).inflate(R.layout.profile_contect_view, null, false);
        scrollView.setHeaderView(headView);
        scrollView.setZoomView(zoomView);
        scrollView.setScrollContentView(contentView);

6.其他

其他的注解、dialog等小编在这里就不介绍了,很多资料,小编把网址给大家贴下来,有兴趣的可以看一下:
推荐一个Android开发懒人库 – ButterKnife
MaterialDialog
BetterSpinner

APP有很多不合理的地方,还请小伙伴们多多包涵哈,多多指正,源码估计元旦回去之后等我完善之后会开源出来的,大家可以多多关注我的博客和github,要是有的小伙伴等不及可以留下邮箱,我会及时关注给你们发源码的。

版权声明:本文为博主原创文章,转载请标明出处。

Android design support library---CollapsingAvatarToolbar分析

先来说说什么是Android design support library:        Android design support library是一个全新的lib库,包含了8个新的materi...
  • dulzihi
  • dulzihi
  • 2015年11月06日 10:17
  • 648

CollapsingAvatarToolbar 头像随ListView滚动缩回到ActionBar特效

CollapsingAvatarToolbar 头像随ListView滚动缩回到ActionBar特效 介绍: CollapsingAvatarToolbar 头像随ListV...

自定义 Material Design风格的提示框

其实在14年谷歌就推出了全新的设计语言Material Design,这种设计语言旨在为手机、平板电脑、台式机和“其他平台”提供更一致、更广泛的“外观和感觉”。简单来说,就是一种扁平化的设置语言,我们...

Android开发(21)--有关Spinner控件的使用说明

下拉列表 Spinner,Spinner是一个每次只能选择所有项的一个项的控件。它的项来自于与之相关联的适配器中。 Spinner的使用,可以极大提高用户的体验性。当需要用户选择的时候,可以提供一个...

一个基于MD风格的android对话框,代码兼容性很好,样式也非常简洁

下面先来几张图看看: 怎么样,看样式还是不错的吧,这是一个从github上找的一个项目 项目地址:https://github.com/drakeet/MaterialDialog写这个文...

MaterialDialog 仿Android 5.0原生的AlertDialog样式的对话框

MaterialDialog仿Android原生的AlertDialog样式的对话框,目的在于解决原生的在Android 5.0以下手机样式丑陋问题。 初次开源项目,如有不足之处,请各位大神多多海涵...

Android Material Design(一)史上最全的材料设计控件大全

主要内容: 本文将要介绍Material design和Support library控件,主要包括TextInputLayout、SwitchCompat、SnackBar、Fl...

Android Design Support Library使用详解

Android Design Support Library使用详解Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Andr...

基于数组实现Java 自定义Stack栈类及应用

栈是存放对象的一种特殊容器,在插入与删除对象时,这种结构遵循后进先出( Last-in-first-out,LIFO)的原则。java本身是有自带Stack类包,为了达到学习目的已经更好深入了解sta...

session的工作原理

session的工作原理 一、术语session 在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含...
  • xys_777
  • xys_777
  • 2011年11月09日 21:20
  • 628
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一款基于Material Desgin设计的APP
举报原因:
原因补充:

(最多只允许输入30个字)