├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── values.xml │ │ │ │ ├── transition.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── colors.xml │ │ │ │ ├── styles.xml │ │ │ │ └── strings.xml │ │ │ ├── drawable-xxhdpi │ │ │ │ ├── book1.jpg │ │ │ │ ├── book2.jpg │ │ │ │ ├── book3.jpg │ │ │ │ ├── ic_favorite.png │ │ │ │ ├── ic_find_in_page_white.png │ │ │ │ └── news_item.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── profile.png │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── layout │ │ │ │ ├── fragment_page.xml │ │ │ │ ├── fragment_example.xml │ │ │ │ ├── fragment_blog.xml │ │ │ │ ├── fragment_detail.xml │ │ │ │ ├── include_toolbar.xml │ │ │ │ ├── custom_tab.xml │ │ │ │ ├── fragment_about.xml │ │ │ │ ├── progress_bar.xml │ │ │ │ ├── activity_recycler_view.xml │ │ │ │ ├── activity_bottom_tab.xml │ │ │ │ ├── navigation_header.xml │ │ │ │ ├── item_view.xml │ │ │ │ ├── fragment_books.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_edittext_fl.xml │ │ │ │ ├── book_item.xml │ │ │ │ ├── activity_appbar_detail.xml │ │ │ │ ├── activity_news_detail.xml │ │ │ │ └── activity_cardview.xml │ │ │ ├── menu │ │ │ │ ├── menu_main.xml │ │ │ │ └── drawer.xml │ │ │ ├── values-w820dp │ │ │ │ └── dimens.xml │ │ │ ├── color │ │ │ │ └── tab_text.xml │ │ │ └── values-v21 │ │ │ │ └── styles.xml │ │ ├── ic_launcher-web.png │ │ ├── java │ │ │ └── com │ │ │ │ └── aswifter │ │ │ │ └── material │ │ │ │ ├── common │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── ThreadPool.java │ │ │ │ ├── Utils.java │ │ │ │ └── AppClient.java │ │ │ │ ├── MaterialApplication.java │ │ │ │ ├── news │ │ │ │ ├── NewsObservable.java │ │ │ │ ├── ConverterName.java │ │ │ │ ├── NewsResponse.java │ │ │ │ ├── NewsSupplier.java │ │ │ │ ├── TopStory.java │ │ │ │ ├── NewsDetailResponse.java │ │ │ │ ├── Story.java │ │ │ │ ├── NewsAdapter.java │ │ │ │ ├── NewsListActivity.java │ │ │ │ └── NewsDetailActivity.java │ │ │ │ ├── book │ │ │ │ ├── OnRefreshObservable.java │ │ │ │ ├── ViewHolder.java │ │ │ │ ├── BookResponse.java │ │ │ │ ├── BooksSupplier.java │ │ │ │ ├── BookDetailActivity.java │ │ │ │ ├── MyAdapter.java │ │ │ │ ├── Book.java │ │ │ │ └── BooksFragment.java │ │ │ │ ├── AboutFragment.java │ │ │ │ ├── widget │ │ │ │ ├── BackHandledFragment.java │ │ │ │ ├── DividerOffsetDecoration.java │ │ │ │ ├── WebViewProgressBar.java │ │ │ │ ├── RecyclerItemClickListener.java │ │ │ │ ├── ProgressWebView.java │ │ │ │ ├── DividerItemDecoration.java │ │ │ │ ├── RefreshLayout.java │ │ │ │ └── CircleImageView.java │ │ │ │ ├── example │ │ │ │ ├── CardViewActivity.java │ │ │ │ ├── DetailFragment.java │ │ │ │ ├── EditTextFLActivity.java │ │ │ │ ├── AppBarDetailActivity.java │ │ │ │ └── BottomTabActivity.java │ │ │ │ ├── BlogFragment.java │ │ │ │ ├── utils │ │ │ │ └── DisplayUtil.java │ │ │ │ ├── ExampleFragment.java │ │ │ │ └── MainActivity.java │ │ ├── assets │ │ │ ├── book_author.txt │ │ │ ├── book_content.txt │ │ │ ├── book_menu.txt │ │ │ └── news.css │ │ └── AndroidManifest.xml │ └── androidTest │ │ └── java │ │ └── com │ │ └── aswifter │ │ └── material │ │ └── ApplicationTest.java ├── proguard-rules.pro ├── build.gradle └── app.iml ├── settings.gradle ├── images ├── demo.apk ├── pic1.png ├── pic2.png ├── cardview.png ├── app-debug.apk └── bookdetail.gif ├── .idea ├── copyright │ └── profiles_settings.xml ├── modules.xml ├── runConfigurations.xml ├── gradle.xml ├── compiler.xml └── misc.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── README.md ├── .gitignore ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' -------------------------------------------------------------------------------- /images/demo.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/images/demo.apk -------------------------------------------------------------------------------- /images/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/images/pic1.png -------------------------------------------------------------------------------- /images/pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/images/pic2.png -------------------------------------------------------------------------------- /app/src/main/res/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /images/cardview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/images/cardview.png -------------------------------------------------------------------------------- /images/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/images/app-debug.apk -------------------------------------------------------------------------------- /images/bookdetail.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/images/bookdetail.gif -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/book1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/drawable-xxhdpi/book1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/book2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/drawable-xxhdpi/book2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/book3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/drawable-xxhdpi/book3.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/mipmap-hdpi/profile.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_favorite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/drawable-xxhdpi/ic_favorite.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_find_in_page_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyangcun/MaterialDesignExample/HEAD/app/src/main/res/drawable-xxhdpi/ic_find_in_page_white.png -------------------------------------------------------------------------------- /app/src/main/res/values/transition.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | transition_book_img 4 | transition_news_img 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/news_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_page.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Aug 11 23:48:59 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | ssss= 4 | distributionPath=wrapper/dists 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_example.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_blog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/common/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.common; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | 5 | /** 6 | * Created by erfli on 6/16/16. 7 | */ 8 | public abstract class BaseActivity extends AppCompatActivity { 9 | protected abstract void initView(); 10 | protected abstract void initRepository(); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 5dp 6 | 56dp 7 | 10dp> 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/assets/book_author.txt: -------------------------------------------------------------------------------- 1 | 凯文·凯利(Kevin Kelly,1952年4月27日~,人们昵称他为 KK), 2 | 他影响了苹果公司的史蒂夫·乔布斯、《连线》杂志的总编克里斯·安德森、《黑客帝国》的导演沃卓斯基兄弟、《少数派报告》的导演史蒂文·斯皮尔伯格;他参与创办了《连线》杂志、发起第一届黑客大会、创作《失 控》……;他是网络文化的发言人和观察者……他是——凯文·凯利 3 | 《连线》(Wired)杂志创始主编。在创办《连线》之前,是《全球概览》杂志(The Whole Earth Catalog,乔布斯最喜欢的杂志)的编辑和出版人。1984年,KK发起了第一届黑客大会(Hackers Conference)。他的文章还出现在《纽约时报》、《经济学人》、《时代》、《科学》等重量级媒体和杂志上。 4 | 凯文·凯利被看作是“网络文化”(Cyberculture)的发言人和观察者,也有人称之为“游侠”(maverick)。 -------------------------------------------------------------------------------- /app/src/main/res/color/tab_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 本APP用来演示Material Design控件的使用。 2 | 3 | ![](http://7xjq5l.com1.z0.glb.clouddn.com/android_transition.gif) 4 |
5 | ![](http://7xjq5l.com1.z0.glb.clouddn.com/appbar_detail.gif) 6 |
7 | ![](http://7xjq5l.com1.z0.glb.clouddn.com/m1.png) 8 |
9 | ![](http://7xjq5l.com1.z0.glb.clouddn.com/m2.png) 10 |
11 | ![](http://7xjq5l.com1.z0.glb.clouddn.com/m3.png) 12 |
13 | ![](http://7xjq5l.com1.z0.glb.clouddn.com/m4.png) 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/aswifter/material/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/common/ThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.common; 2 | 3 | import java.util.concurrent.ScheduledThreadPoolExecutor; 4 | import java.util.concurrent.ThreadPoolExecutor; 5 | 6 | /** 7 | * Created by erfli on 6/14/16. 8 | */ 9 | public class ThreadPool { 10 | public static ThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(6); 11 | public static void clearExecut(){ 12 | executor.getQueue().clear(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/MaterialApplication.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material; 2 | 3 | import android.app.Application; 4 | 5 | import com.aswifter.material.common.AppClient; 6 | import com.aswifter.material.utils.DisplayUtil; 7 | 8 | /** 9 | * Created by erfli on 6/14/16. 10 | */ 11 | public class MaterialApplication extends Application{ 12 | @Override 13 | public void onCreate() { 14 | super.onCreate(); 15 | AppClient.initAppClient(); 16 | DisplayUtil.init(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/news/NewsObservable.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.news; 2 | 3 | import com.google.android.agera.BaseObservable; 4 | 5 | /** 6 | * Created by erfli on 6/15/16. 7 | */ 8 | public class NewsObservable extends BaseObservable{ 9 | 10 | NewsSupplier supplier; 11 | public NewsObservable(NewsSupplier supplier){ 12 | this.supplier = supplier; 13 | } 14 | public void refreshNews(String key){ 15 | supplier.setNewsKey(key); 16 | dispatchUpdate(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/news/ConverterName.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.news; 2 | 3 | /** 4 | * Created by erfli on 6/18/16. 5 | */ 6 | 7 | import java.lang.annotation.Documented; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | import static java.lang.annotation.ElementType.METHOD; 12 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 13 | @Documented 14 | @Target(METHOD) 15 | @Retention(RUNTIME) 16 | public @interface ConverterName 17 | { 18 | String value() default "gson"; 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/assets/book_content.txt: -------------------------------------------------------------------------------- 1 | 《失控》,全名为《失控:机器、社会与经济的新生物学》(Out of Control: The New Biology of Machines, Social Systems, and the Economic World)。 2 | 2006年,《长尾》作者克里斯·安德森在亚马逊网站上这样评价该书: 3 | “这可能是90年代最重要的一本书”,并且是“少有的一年比一年卖得好的书”。“尽管书中的一些例子在十几年后可能有些过时,但(它们所表达的)信息却越来越成为真知灼见”。“在那时人们还无法想象博客和维基等大众智慧的突起,但凯利却分毫不差地预见到了。这可能是过去十年来最聪明的一本书。” 4 | 这是一部思考人类社会(或更一般意义上的复杂系统)进化的“大部头”著作,对于那些不惧于“头脑体操”的读者来说,必然会开卷有益。 5 | 《失控》成书于1994年,作者是《连线》杂志的创始主编凯文·凯利。这本书所记述的,是他对当时科技、社会和经济最前沿的一次漫游,以及借此所窥得的未来图景。 6 | 书中提到并且今天正在兴起或大热的概念包括:大众智慧、云计算、物联网、虚拟现实、敏捷开发、协作、双赢、共生、共同进化、网络社区、网络经济,等等。说它是一本“预言式”的书并不为过。其中必定还隐藏着我们尚未印证或窥破的对未来的“预言”。 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | build/ 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | *.iml 30 | .idea 31 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 32 | .gradle 33 | build/ 34 | 35 | *~ 36 | *.swp -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/news/NewsResponse.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.news; 2 | 3 | import java.util.List; 4 | 5 | 6 | public class NewsResponse{ 7 | private List stories; 8 | private String date; 9 | public NewsResponse(){ 10 | 11 | } 12 | 13 | public void setStories(List stories) { 14 | this.stories = stories; 15 | } 16 | 17 | public List getStories() { 18 | return stories; 19 | } 20 | 21 | public void setDate(String date) { 22 | this.date = date; 23 | } 24 | 25 | public String getDate() { 26 | return date; 27 | } 28 | 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/book/OnRefreshObservable.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.book; 2 | 3 | import android.support.v4.widget.SwipeRefreshLayout; 4 | 5 | import com.google.android.agera.BaseObservable; 6 | 7 | public class OnRefreshObservable extends BaseObservable 8 | implements SwipeRefreshLayout.OnRefreshListener { 9 | 10 | /** 11 | * Triggered when the associated {@link SwipeRefreshLayout} is refreshed by the user. The event 12 | * is passed on to the observers, using the {@link UpdateDispatcher} provided by {@link 13 | * BaseObservable}. 14 | */ 15 | @Override 16 | public void onRefresh() { 17 | dispatchUpdate(); 18 | } 19 | } -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/AboutFragment.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | /** 11 | * Created by Chenyc on 15/6/27. 12 | */ 13 | public class AboutFragment extends Fragment { 14 | 15 | @Nullable 16 | @Override 17 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 18 | View view = inflater.inflate(R.layout.fragment_about, null); 19 | 20 | return view; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\adt-bundle-windows-x86_64-20140624\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/custom_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/book/ViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.book; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.aswifter.material.R; 9 | 10 | /** 11 | * Created by erfli on 6/15/16. 12 | */ 13 | public class ViewHolder extends RecyclerView.ViewHolder { 14 | // each data item is just a string in this case 15 | public ImageView ivBook; 16 | public TextView tvTitle; 17 | public TextView tvDesc; 18 | 19 | public int position; 20 | 21 | public ViewHolder(View v) { 22 | super(v); 23 | ivBook = (ImageView) v.findViewById(R.id.ivBook); 24 | tvTitle = (TextView) v.findViewById(R.id.tvTitle); 25 | tvDesc = (TextView) v.findViewById(R.id.tvDesc); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #009688 4 | #00897b 5 | #B2DFDB 6 | #ffb74d 7 | #212121 8 | #727272 9 | #FFFFFF 10 | #B6B6B6 11 | #E8E8E8 12 | #ffffff 13 | 14 | #FFF5F5F5 15 | #eeeeee 16 | 17 | #d62d20 18 | #0057e7 19 | #008744 20 | #ffa700 21 | 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | org.gradle.parallel=true -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 16 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/progress_bar.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/menu/drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 14 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/book/BookResponse.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.book; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by erfli on 6/14/16. 8 | */ 9 | public class BookResponse { 10 | public int count; 11 | public int start; 12 | public int total; 13 | public ArrayList books; 14 | 15 | public int getCount() { 16 | return count; 17 | } 18 | 19 | public int getStart() { 20 | return start; 21 | } 22 | 23 | public int getTotal() { 24 | return total; 25 | } 26 | 27 | public ArrayList getBooks() { 28 | return books; 29 | } 30 | 31 | public void setCount(int count) { 32 | this.count = count; 33 | } 34 | 35 | public void setStart(int start) { 36 | this.start = start; 37 | } 38 | 39 | public void setTotal(int total) { 40 | this.total = total; 41 | } 42 | 43 | public void setBooks(ArrayList books) { 44 | this.books = books; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_recycler_view.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 15 | 16 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/widget/BackHandledFragment.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.widget; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | 6 | public abstract class BackHandledFragment extends Fragment { 7 | protected BackHandlerInterface backHandlerInterface; 8 | 9 | public abstract String getTagText(); 10 | 11 | public abstract boolean onBackPressed(); 12 | 13 | @Override 14 | public void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | if (!(getActivity() instanceof BackHandlerInterface)) { 17 | throw new ClassCastException("Hosting activity must implement BackHandlerInterface"); 18 | } else { 19 | backHandlerInterface = (BackHandlerInterface) getActivity(); 20 | } 21 | } 22 | 23 | @Override 24 | public void onStart() { 25 | super.onStart(); 26 | 27 | // Mark this fragment as the selected Fragment. 28 | backHandlerInterface.setSelectedFragment(this); 29 | } 30 | 31 | public interface BackHandlerInterface { 32 | public void setSelectedFragment(BackHandledFragment backHandledFragment); 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_bottom_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 17 | 18 | 19 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/navigation_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 21 | 22 | 23 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 23 | 24 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/example/CardViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.example; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.View; 8 | 9 | import com.aswifter.material.R; 10 | 11 | /** 12 | * Created by Chenyc on 15/6/28. 13 | */ 14 | public class CardViewActivity extends AppCompatActivity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_cardview); 20 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 21 | toolbar.setTitle(R.string.title_book); 22 | setSupportActionBar(toolbar); 23 | getSupportActionBar().setHomeButtonEnabled(true); 24 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 25 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 26 | @Override 27 | public void onClick(View view) { 28 | onBackPressed(); 29 | } 30 | }); 31 | } 32 | 33 | 34 | public void goDetail(View view){ 35 | Intent intent = new Intent(this,AppBarDetailActivity.class); 36 | startActivity(intent); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/widget/DividerOffsetDecoration.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.widget; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.view.View; 11 | 12 | /* 13 | * Copyright (C) 2014 The Android Open Source Project 14 | * 15 | * Licensed under the Apache License, Version 2.0 (the "License"); 16 | * you may not use this file except in compliance with the License. 17 | * You may obtain a copy of the License at 18 | * 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an " IS" BASIS, 23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | */ 27 | public class DividerOffsetDecoration extends RecyclerView.ItemDecoration { 28 | @Override 29 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 30 | outRect.bottom = 30; 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_books.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 13 | 14 | 15 | 26 | 27 | 28 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 13 | 14 | 17 | 18 | 19 | 26 | 27 | 28 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/example/DetailFragment.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.example; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import com.aswifter.material.R; 12 | 13 | /** 14 | * Created by Chenyc on 2015/6/29. 15 | */ 16 | public class DetailFragment extends Fragment { 17 | 18 | public static DetailFragment newInstance(String info) { 19 | Bundle args = new Bundle(); 20 | DetailFragment fragment = new DetailFragment(); 21 | args.putString("info", info); 22 | fragment.setArguments(args); 23 | return fragment; 24 | } 25 | 26 | 27 | @Nullable 28 | @Override 29 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 30 | View view = inflater.inflate(R.layout.fragment_detail, null); 31 | TextView tvInfo = (TextView) view.findViewById(R.id.tvInfo); 32 | tvInfo.setText(getArguments().getString("info")); 33 | // tvInfo.setOnClickListener(new View.OnClickListener() { 34 | // @Override 35 | // public void onClick(View v) { 36 | // Snackbar.make(v,"hello",Snackbar.LENGTH_SHORT).show(); 37 | // } 38 | // }); 39 | return view; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/BlogFragment.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import com.aswifter.material.widget.BackHandledFragment; 10 | import com.aswifter.material.widget.ProgressWebView; 11 | 12 | /** 13 | * Created by Chenyc on 15/6/27. 14 | */ 15 | public class BlogFragment extends BackHandledFragment { 16 | 17 | private ProgressWebView mWebView; 18 | 19 | @Nullable 20 | @Override 21 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 22 | View view = inflater.inflate(R.layout.fragment_blog, null); 23 | mWebView = (ProgressWebView) view.findViewById(R.id.webView); 24 | mWebView.getSettings().setJavaScriptEnabled(true); 25 | mWebView.loadUrl("http://www.aswifter.com/"); 26 | return view; 27 | } 28 | 29 | @Override 30 | public void onActivityCreated(Bundle savedInstanceState) { 31 | super.onActivityCreated(savedInstanceState); 32 | } 33 | 34 | @Override 35 | public String getTagText() { 36 | return null; 37 | } 38 | 39 | @Override 40 | public boolean onBackPressed() { 41 | if(mWebView.canGoBack()){ 42 | mWebView.goBack(); 43 | return true; 44 | } 45 | 46 | return false; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/news/NewsSupplier.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.news; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.text.TextUtils; 5 | 6 | import com.aswifter.material.common.AppClient; 7 | import com.google.android.agera.Result; 8 | import com.google.android.agera.Supplier; 9 | 10 | import java.io.IOException; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by erfli on 6/15/16. 15 | */ 16 | public class NewsSupplier implements Supplier>> { 17 | 18 | private String newsKey = "latest"; 19 | @NonNull 20 | @Override 21 | public Result> get() { 22 | List stories = getStoryList(); 23 | if(stories == null){ 24 | return Result.failure(); 25 | }else{ 26 | return Result.success(stories); 27 | } 28 | } 29 | 30 | private ListgetStoryList(){ 31 | try { 32 | if(TextUtils.isEmpty(newsKey)){ 33 | return AppClient.httpService.getLatestNews().execute().body().getStories(); 34 | }else 35 | return AppClient.httpService.getHistoryNews(newsKey).execute().body().getStories(); 36 | } catch (IOException e) { 37 | e.printStackTrace(); 38 | return null; 39 | } 40 | } 41 | 42 | public void setNewsKey(@NonNull String key){ 43 | if(TextUtils.isEmpty(key)){ 44 | newsKey = ""; 45 | }else { 46 | newsKey = key; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 28 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/widget/WebViewProgressBar.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | 9 | import com.aswifter.material.R; 10 | 11 | 12 | public class WebViewProgressBar extends View { 13 | private int progress = 1; 14 | private final static int HEIGHT = 5; 15 | private Paint paint; 16 | private final static int colors[] = new int[]{}; 17 | public WebViewProgressBar(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | public WebViewProgressBar(Context context) { 22 | super(context); 23 | // LinearGradient shader = new LinearGradient( 24 | // 0, 0, 25 | // 100, HEIGHT, 26 | // colors, 27 | // null, 28 | // Shader.TileMode.MIRROR); 29 | paint=new Paint(Paint.DITHER_FLAG); 30 | paint.setStyle(Paint.Style.STROKE); 31 | paint.setStrokeWidth(HEIGHT); 32 | paint.setAntiAlias(true); 33 | paint.setColor(context.getResources().getColor(R.color.primary_light)); 34 | // paint.setShader(shader); 35 | } 36 | public void setProgress(int progress){ 37 | this.progress = progress; 38 | invalidate(); 39 | } 40 | 41 | @Override 42 | protected void onDraw(Canvas canvas) { 43 | canvas.drawRect(0, 0, getWidth() * progress / 100, HEIGHT, paint); 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 18 | 19 | 20 | 27 | 28 | 29 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/example/EditTextFLActivity.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.example; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.support.v7.widget.Toolbar; 6 | import android.view.View; 7 | 8 | import com.aswifter.material.R; 9 | 10 | /** 11 | * Created by chenyc on 2015/6/25. 12 | */ 13 | public class EditTextFLActivity extends AppCompatActivity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_edittext_fl); 19 | 20 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 21 | toolbar.setTitle(R.string.title_login); 22 | setSupportActionBar(toolbar); 23 | getSupportActionBar().setHomeButtonEnabled(true); 24 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 25 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 26 | @Override 27 | public void onClick(View view) { 28 | onBackPressed(); 29 | } 30 | }); 31 | 32 | findViewById(R.id.btnLogin).setOnClickListener(new View.OnClickListener() { 33 | @Override 34 | public void onClick(View v) { 35 | finish(); 36 | } 37 | }); 38 | // TextInputLayout textInputEmail =(TextInputLayout)findViewById(R.id.textInputEmail); 39 | // textInputEmail.setErrorEnabled(true); 40 | // textInputEmail.setError("Error Message"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/common/Utils.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.common; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.graphics.Point; 6 | import android.os.Build; 7 | import android.view.Display; 8 | import android.view.WindowManager; 9 | 10 | /** 11 | * Created by froger_mcs on 05.11.14. 12 | */ 13 | public class Utils { 14 | private static int screenWidth = 0; 15 | private static int screenHeight = 0; 16 | 17 | public static int dpToPx(int dp) { 18 | return (int) (dp * Resources.getSystem().getDisplayMetrics().density); 19 | } 20 | 21 | public static int getScreenHeight(Context c) { 22 | if (screenHeight == 0) { 23 | WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); 24 | Display display = wm.getDefaultDisplay(); 25 | Point size = new Point(); 26 | display.getSize(size); 27 | screenHeight = size.y; 28 | } 29 | 30 | return screenHeight; 31 | } 32 | 33 | public static int getScreenWidth(Context c) { 34 | if (screenWidth == 0) { 35 | WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); 36 | Display display = wm.getDefaultDisplay(); 37 | Point size = new Point(); 38 | display.getSize(size); 39 | screenWidth = size.x; 40 | } 41 | 42 | return screenWidth; 43 | } 44 | 45 | public static boolean isAndroid5() { 46 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/aswifter/material/widget/RecyclerItemClickListener.java: -------------------------------------------------------------------------------- 1 | package com.aswifter.material.widget; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.GestureDetector; 6 | import android.view.MotionEvent; 7 | import android.view.View; 8 | 9 | 10 | public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { 11 | private OnItemClickListener mListener; 12 | 13 | public interface OnItemClickListener { 14 | void onItemClick(View view, int position); 15 | } 16 | 17 | GestureDetector mGestureDetector; 18 | 19 | public RecyclerItemClickListener(Context context, OnItemClickListener listener) { 20 | mListener = listener; 21 | mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 22 | @Override public boolean onSingleTapUp(MotionEvent e) { 23 | return true; 24 | } 25 | }); 26 | } 27 | 28 | @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { 29 | View childView = view.findChildViewUnder(e.getX(), e.getY()); 30 | if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { 31 | mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); 32 | } 33 | return false; 34 | } 35 | 36 | @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } 37 | 38 | @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 39 | // do nothing 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_edittext_fl.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 14 | 15 | 21 | 22 | 23 | 26 | 27 | 33 | 34 | 35 | 36 | 37 |