源碼小編已經上傳到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,要是有的小夥伴等不及可以留下郵箱,我會及時關注給你們發源碼的。