├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── jsoup-1.8.2.jar │ └── universal-image-loader-1.9.5.jar ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── yasic │ │ │ └── diycode │ │ │ ├── Adapter │ │ │ ├── BaseAdapter.java │ │ │ ├── TopicDetailAdapter.java │ │ │ ├── TopicListAdapter.java │ │ │ └── ViewPagerMainInterfaceAdapter.java │ │ │ ├── Bean │ │ │ ├── CallbackBean.java │ │ │ ├── TopicDetailBean.java │ │ │ ├── TopicItemBean.java │ │ │ └── TopicReplyBean.java │ │ │ ├── MainActivity.java │ │ │ ├── Model │ │ │ ├── ITopicModel.java │ │ │ └── TopicModel.java │ │ │ ├── Presenter │ │ │ ├── BasePresenterActivity.java │ │ │ ├── BasePresenterFragment.java │ │ │ ├── ContainerPresenter.java │ │ │ ├── PersonalInfoPresenter.java │ │ │ ├── SettingPresenter.java │ │ │ ├── TopicDetailPresenter.java │ │ │ └── TopicListPresenter.java │ │ │ ├── Util │ │ │ ├── OkhttpUtil.java │ │ │ └── UrlImageGetter.java │ │ │ └── View │ │ │ ├── BaseViewInterface.java │ │ │ ├── ContainerView.java │ │ │ ├── PersonalInfoView.java │ │ │ ├── Settingview.java │ │ │ ├── TopicDetailView.java │ │ │ └── TopicListView.java │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_reply_blue_a400_24dp.png │ │ ├── ic_star_border_pink_400_24dp.png │ │ └── ic_star_pink_400_24dp.png │ │ ├── drawable-mdpi │ │ ├── ic_reply_blue_a400_24dp.png │ │ ├── ic_star_border_pink_400_24dp.png │ │ └── ic_star_pink_400_24dp.png │ │ ├── drawable-xhdpi │ │ ├── ic_reply_blue_a400_24dp.png │ │ ├── ic_star_border_pink_400_24dp.png │ │ └── ic_star_pink_400_24dp.png │ │ ├── drawable-xxhdpi │ │ ├── ic_reply_blue_a400_24dp.png │ │ ├── ic_star_border_pink_400_24dp.png │ │ └── ic_star_pink_400_24dp.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_reply_blue_a400_24dp.png │ │ ├── ic_star_border_pink_400_24dp.png │ │ └── ic_star_pink_400_24dp.png │ │ ├── layout │ │ ├── activity_container.xml │ │ ├── activity_main.xml │ │ ├── activity_topicdetail.xml │ │ ├── content_comment.xml │ │ ├── content_headoftopicdetail.xml │ │ ├── content_main.xml │ │ ├── content_topichead.xml │ │ ├── fragment_topiclist.xml │ │ └── item_topiclist.xml │ │ ├── menu │ │ ├── menu_main.xml │ │ ├── menu_topic.xml │ │ └── menu_topic_detail.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── yasic │ └── diycode │ ├── ApplicationTest.java │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | DiyCode -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DiyCodeForAndroid 2 | http://diycode.cc/topics Diycode社区Android客户端 3 | 4 | ###功能脑图地址及截图<需要MindMup>: 5 | https://drive.google.com/open?id=0B2xOdsa2mISLdkRxWHZSb0tqaFk 6 | 7 | https://drive.google.com/open?id=0B2xOdsa2mISLbkFtRDc2dGlsUHM 8 | ![](http://diycode.b0.upaiyun.com/photo/2016/c95ac3be65846b510a273611da7e2cc8.png) 9 | ![](http://diycode.b0.upaiyun.com/photo/2016/f414b706a9411b44f8f63e8e00220340.jpg) 10 | 11 | ###简述 12 | * MVP架构 + RXJava/RXAndroid 13 | * 暂时在model中使用OKhttp进行网络爬虫获取数据,期待转入成熟API 14 | * 凡是完成的部分都会在脑图中用绿色表示 15 | * 网络请求使用okhttp框架 16 | * 图片显示使用fresco框架 17 | 18 | ###5月23日更新 19 | * 完成社区话题列表显示 20 | * 完成话题详情元素显示 21 | * Recyclerview加入头部布局,以达到全部元素在一个recyclervew显示的目的 22 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.yasic.diycode" 9 | minSdkVersion 14 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.3.0' 26 | compile 'com.android.support:design:23.3.0' 27 | compile 'com.google.android:flexbox:0.1.2' 28 | compile 'io.reactivex:rxandroid:1.1.0' 29 | compile 'io.reactivex:rxjava:1.1.0' 30 | compile 'com.squareup.okhttp:okhttp:2.4.0' 31 | compile 'com.android.support:cardview-v7:23.3.0' 32 | compile 'com.facebook.fresco:fresco:0.9.0+' 33 | compile files('libs/jsoup-1.8.2.jar') 34 | compile files('libs/universal-image-loader-1.9.5.jar') 35 | testCompile 'junit:junit:4.12' 36 | } 37 | -------------------------------------------------------------------------------- /app/libs/jsoup-1.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/libs/jsoup-1.8.2.jar -------------------------------------------------------------------------------- /app/libs/universal-image-loader-1.9.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/libs/universal-image-loader-1.9.5.jar -------------------------------------------------------------------------------- /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:\Users\ESIR\AppData\Local\Android\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 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Adapter/BaseAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by ESIR on 2016/3/18. 12 | */ 13 | public abstract class BaseAdapter extends RecyclerView.Adapter { 14 | protected List objectList; 15 | protected Context context; 16 | protected OnItemClickListener onItemClickListener; 17 | 18 | @Override 19 | public VH onCreateViewHolder(ViewGroup parent, int viewType) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public void onBindViewHolder(VH holder, int position) { 25 | 26 | } 27 | 28 | @Override 29 | public int getItemCount() { 30 | if(objectList == null){ 31 | return 0; 32 | }else { 33 | return objectList.size(); 34 | } 35 | } 36 | 37 | /** 38 | * 提示数据有了变动,刷新数据的方法 39 | * 40 | * @param objectList 变动之后的list 41 | */ 42 | public void refresh(List objectList) { 43 | this.objectList = objectList; 44 | notifyDataSetChanged(); 45 | } 46 | 47 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) { 48 | this.onItemClickListener = onItemClickListener; 49 | } 50 | 51 | /** 52 | * 点击事件的接口 53 | */ 54 | public interface OnItemClickListener { 55 | 56 | /** 57 | * 短点击 58 | * 59 | * @param v 被点击的对象 60 | * @param position 被点击的view的位置 61 | */ 62 | void onItemClick(View v, int position); 63 | 64 | /** 65 | * 长按 66 | * 67 | * @param v 被点击的对象 68 | * @param position 被点击的view的位置 69 | */ 70 | void onItemLongCick(View v, int position); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Adapter/TopicDetailAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Adapter; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.drawable.BitmapDrawable; 6 | import android.graphics.drawable.Drawable; 7 | import android.net.Uri; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.text.Html; 10 | import android.text.Spanned; 11 | import android.util.Log; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.ImageButton; 16 | import android.widget.TextView; 17 | 18 | import com.facebook.drawee.view.SimpleDraweeView; 19 | import com.nostra13.universalimageloader.core.ImageLoader; 20 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 21 | import com.nostra13.universalimageloader.core.assist.FailReason; 22 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; 23 | import com.yasic.diycode.Bean.TopicDetailBean; 24 | import com.yasic.diycode.Bean.TopicReplyBean; 25 | import com.yasic.diycode.R; 26 | 27 | /** 28 | * Created by Yasic on 2016/5/23. 29 | */ 30 | public class TopicDetailAdapter extends RecyclerView.Adapter { 31 | private static final int TYPE_HEADER = 0; 32 | private static final int TYPE_NORMAL = 1; 33 | 34 | private TopicDetailBean topicDetailBean = null; 35 | 36 | private View headerView = null; 37 | 38 | private Context context; 39 | 40 | public TopicDetailAdapter(Context context, TopicDetailBean topicDetailBean){ 41 | this.topicDetailBean = topicDetailBean; 42 | this.context = context; 43 | } 44 | 45 | public void setHeaderView(View headerView){ 46 | this.headerView = headerView; 47 | notifyItemInserted(0); 48 | } 49 | 50 | public void refreshData(TopicDetailBean topicDetailBean){ 51 | this.topicDetailBean = topicDetailBean; 52 | notifyDataSetChanged(); 53 | } 54 | 55 | @Override 56 | public int getItemViewType(int position) { 57 | if (headerView == null){ 58 | return TYPE_NORMAL; 59 | } 60 | if (position == 0){ 61 | return TYPE_HEADER; 62 | } 63 | return TYPE_NORMAL; 64 | } 65 | 66 | @Override 67 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 68 | if (headerView != null && viewType == TYPE_HEADER){ 69 | return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.content_headoftopicdetail, parent, false)); 70 | } 71 | else { 72 | return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.content_comment, parent, false)); 73 | } 74 | } 75 | 76 | @Override 77 | public void onBindViewHolder(final MyViewHolder holder, int position) { 78 | if (getItemViewType(position) == TYPE_HEADER){ 79 | holder.tvTitle.setText(topicDetailBean.getTitle()); 80 | holder.tvType.setText(topicDetailBean.getType()); 81 | holder.tvAuthor.setText(topicDetailBean.getAuthor()); 82 | Uri uri = Uri.parse(topicDetailBean.getHeadPortrait()); 83 | Log.i("uri", uri.toString()); 84 | holder.sdvAuthorHeadPortrait.setImageURI(uri); 85 | Spanned spanned = Html.fromHtml(topicDetailBean.getArticle(), new Html.ImageGetter() { 86 | @Override 87 | public Drawable getDrawable(final String source) { 88 | ImageLoader imageLoader = ImageLoader.getInstance(); 89 | imageLoader.init(ImageLoaderConfiguration.createDefault(context)); 90 | imageLoader.loadImage(source, 91 | new ImageLoadingListener() { 92 | @Override 93 | public void onLoadingStarted(String s, View view) { 94 | 95 | } 96 | 97 | @Override 98 | public void onLoadingFailed(String s, View view, FailReason failReason) { 99 | 100 | } 101 | 102 | @Override 103 | public void onLoadingComplete(String s, View view, Bitmap bitmap) { 104 | if (bitmap != null) { 105 | Drawable drawable = new BitmapDrawable( 106 | context.getResources(), bitmap); 107 | drawable.setBounds(0, 0, 108 | 500, 109 | 300); 110 | holder.tvTopicContent.requestLayout(); 111 | System.out.println("loaded"); 112 | } 113 | } 114 | 115 | @Override 116 | public void onLoadingCancelled(String s, View view) { 117 | 118 | } 119 | }); 120 | return null; 121 | /*Observable.create(new Observable.OnSubscribe() { 122 | @Override 123 | public void call(Subscriber subscriber) { 124 | InputStream inputStream = null; 125 | try { 126 | inputStream = (InputStream)new URL(source).getContent(); 127 | Drawable d = Drawable.createFromStream(inputStream, "src"); 128 | d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); 129 | inputStream.close(); 130 | subscriber.onNext(d); 131 | subscriber.onCompleted(); 132 | }catch (Exception e){ 133 | subscriber.onNext(null); 134 | subscriber.onCompleted(); 135 | } 136 | } 137 | }) 138 | .subscribeOn(Schedulers.io()) 139 | .observeOn(AndroidSchedulers.mainThread()) 140 | .subscribe(new Action1() { 141 | @Override 142 | public void call(Drawable drawable) { 143 | holder.tvTopicContent.requestLayout(); 144 | } 145 | });*/ 146 | } 147 | }, null); 148 | holder.tvTopicContent.setText(spanned); 149 | //holder.tvTopicContent.requestLayout(); 150 | //holder.tvTopicContent.setText(topicDetailBean.getArticle()); 151 | return; 152 | } 153 | final int pos = getRealPosition(holder); 154 | final TopicReplyBean topicReplyBean = topicDetailBean.getTopicReplyBeanList().get(pos); 155 | onBind(holder, pos, topicReplyBean); 156 | } 157 | 158 | public void onBind(MyViewHolder viewHolder, int RealPosition, TopicReplyBean topicReplyBean) { 159 | viewHolder.tvReplierNickName.setText(topicReplyBean.getAuthor()); 160 | viewHolder.tvComment.setText(topicReplyBean.getReplyInfo()); 161 | viewHolder.tvPublishTime.setText(topicReplyBean.getPublishTime()); 162 | Uri uri = Uri.parse(topicReplyBean.getHeadPortrait()); 163 | viewHolder.sdvReplierHeadPortrait.setImageURI(uri); 164 | //viewHolder.btStar.setText(topicReplyBean.getStartNumber()); 165 | } 166 | 167 | @Override 168 | public int getItemCount() { 169 | return headerView == null ? topicDetailBean.getTopicReplyBeanList().size() : topicDetailBean.getTopicReplyBeanList().size() + 1; 170 | } 171 | 172 | /** 173 | * 获取真实位置 174 | * @param holder 传入holder 175 | * @return 如果有头部布局则返回位置减1 176 | */ 177 | public int getRealPosition(RecyclerView.ViewHolder holder) { 178 | int position = holder.getPosition(); 179 | return headerView == null ? position : position - 1; 180 | } 181 | 182 | public class MyViewHolder extends RecyclerView.ViewHolder{ 183 | TextView tvReplierNickName, tvComment, tvPublishTime, tvTitle, tvType, tvAuthor, tvTopicContent; 184 | ImageButton btStar; 185 | SimpleDraweeView sdvReplierHeadPortrait, sdvAuthorHeadPortrait; 186 | public MyViewHolder(View itemView) { 187 | super(itemView); 188 | tvReplierNickName = (TextView) itemView.findViewById(R.id.tv_ReplierNickName); 189 | tvComment = (TextView) itemView.findViewById(R.id.tv_Comment); 190 | tvPublishTime = (TextView) itemView.findViewById(R.id.tv_PublishTime); 191 | btStar = (ImageButton) itemView.findViewById(R.id.bt_Star); 192 | tvTitle = (TextView) itemView.findViewById(R.id.tv_Title); 193 | tvType = (TextView) itemView.findViewById(R.id.tv_Type); 194 | tvAuthor = (TextView) itemView.findViewById(R.id.tv_Author); 195 | tvTopicContent = (TextView) itemView.findViewById(R.id.tv_TopicContent); 196 | sdvReplierHeadPortrait = (SimpleDraweeView) itemView.findViewById(R.id.sdv_ReplierHeadPortrait); 197 | sdvAuthorHeadPortrait = (SimpleDraweeView) itemView.findViewById(R.id.sdv_AuthorHeadPortrait); 198 | } 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Adapter/TopicListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.RelativeLayout; 9 | import android.widget.TextView; 10 | 11 | import com.yasic.diycode.Bean.TopicItemBean; 12 | import com.yasic.diycode.R; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by ESIR on 2016/3/18. 18 | */ 19 | public class TopicListAdapter extends BaseAdapter { 20 | 21 | public TopicListAdapter(Context context, List topicItemBeanList) { 22 | this.context = context; 23 | this.objectList = topicItemBeanList; 24 | } 25 | 26 | @Override 27 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 28 | return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_topiclist,parent,false)); 29 | } 30 | 31 | @Override 32 | public void onBindViewHolder(final MyViewHolder holder, final int position) { 33 | if (onItemClickListener != null) { 34 | holder.liTopicList.setOnClickListener(new View.OnClickListener() { 35 | @Override 36 | public void onClick(View v) { 37 | onItemClickListener.onItemClick(holder.liTopicList,position); 38 | } 39 | }); 40 | } 41 | holder.tvTitle.setText(objectList.get(position).getTitle()); 42 | holder.tvType.setText(objectList.get(position).getType()); 43 | holder.tvAuthor.setText(objectList.get(position).getAuthor()); 44 | holder.tvLastReply.setText(objectList.get(position).getLastReply()); 45 | holder.tvTotalReply.setText(objectList.get(position).getTotalReply()); 46 | super.onBindViewHolder(holder, position); 47 | } 48 | 49 | public class MyViewHolder extends RecyclerView.ViewHolder{ 50 | private TextView tvTitle, tvType, tvAuthor, tvLastReply, tvTotalReply; 51 | private RelativeLayout liTopicList; 52 | public MyViewHolder(View itemView) { 53 | super(itemView); 54 | liTopicList = (RelativeLayout) itemView.findViewById(R.id.li_TopicList); 55 | tvTitle = (TextView) itemView.findViewById(R.id.tv_Title); 56 | tvType = (TextView) itemView.findViewById(R.id.tv_Type); 57 | tvAuthor = (TextView) itemView.findViewById(R.id.tv_Author); 58 | tvLastReply = (TextView) itemView.findViewById(R.id.tv_LastReply); 59 | tvTotalReply = (TextView) itemView.findViewById(R.id.tv_TotalReply); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Adapter/ViewPagerMainInterfaceAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Adapter; 2 | 3 | import android.support.v4.app.Fragment; 4 | import android.support.v4.app.FragmentManager; 5 | import android.support.v4.app.FragmentPagerAdapter; 6 | 7 | import com.yasic.diycode.Presenter.BasePresenterFragment; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by ESIR on 2016/4/6. 13 | */ 14 | public class ViewPagerMainInterfaceAdapter extends FragmentPagerAdapter { 15 | private List tabTitleList; 16 | private List fragmentList; 17 | 18 | public ViewPagerMainInterfaceAdapter(FragmentManager fm, List tabTitleList, List fragmentList) { 19 | super(fm); 20 | this.tabTitleList = tabTitleList; 21 | this.fragmentList = fragmentList; 22 | } 23 | 24 | @Override 25 | public Fragment getItem(int position) { 26 | return fragmentList.get(position); 27 | } 28 | 29 | @Override 30 | public int getCount() { 31 | return tabTitleList == null ? 0 : tabTitleList.size(); 32 | } 33 | 34 | @Override 35 | public CharSequence getPageTitle(int position) { 36 | return tabTitleList.get(position); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Bean/CallbackBean.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Bean; 2 | 3 | /** 4 | * Created by Yasic on 2016/5/18. 5 | */ 6 | public class CallbackBean { 7 | private String code; 8 | private String errorMessage; 9 | private T response; 10 | public CallbackBean(String code, String errorMessage, T response){ 11 | this.code = code; 12 | this.errorMessage = errorMessage; 13 | this.response = response; 14 | } 15 | 16 | public String getCode() { 17 | return code; 18 | } 19 | 20 | public String getErrorMessage() { 21 | return errorMessage; 22 | } 23 | 24 | public void setResponse(T response) { 25 | this.response = response; 26 | } 27 | 28 | public void setCode(String code) { 29 | this.code = code; 30 | } 31 | 32 | public void setErrorMessage(String errorMessage) { 33 | this.errorMessage = errorMessage; 34 | } 35 | 36 | public T getResponse() { 37 | return response; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Bean/TopicDetailBean.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Bean; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by Yasic on 2016/5/18. 7 | */ 8 | public class TopicDetailBean { 9 | private String title; 10 | private String publishTime; 11 | private String author; 12 | private String type; 13 | private String watchedNumber; 14 | private String article; 15 | private String headPortrait; 16 | private String startNumber; 17 | private List topicReplyBeanList; 18 | 19 | public TopicDetailBean(String title, String publishTime, String author, String type, String watchedNumber, String article, String headPortrait, String startNumber, List topicReplyBeanList) { 20 | this.title = title; 21 | this.publishTime = publishTime; 22 | this.author = author; 23 | this.type = type; 24 | this.watchedNumber = watchedNumber; 25 | this.article = article; 26 | this.headPortrait = headPortrait; 27 | this.startNumber = startNumber; 28 | this.topicReplyBeanList = topicReplyBeanList; 29 | } 30 | 31 | public String getTitle() { 32 | return title; 33 | } 34 | 35 | public String getPublishTime() { 36 | return publishTime; 37 | } 38 | 39 | public String getAuthor() { 40 | return author; 41 | } 42 | 43 | public String getType() { 44 | return type; 45 | } 46 | 47 | public String getWatchedNumber() { 48 | return watchedNumber; 49 | } 50 | 51 | public String getArticle() { 52 | return article; 53 | } 54 | 55 | public String getHeadPortrait() { 56 | return headPortrait; 57 | } 58 | 59 | public List getTopicReplyBeanList() { 60 | return topicReplyBeanList; 61 | } 62 | 63 | public String getStartNumber() { 64 | return startNumber; 65 | } 66 | 67 | public void setTitle(String title) { 68 | this.title = title; 69 | } 70 | 71 | public void setPublishTime(String publishTime) { 72 | this.publishTime = publishTime; 73 | } 74 | 75 | public void setAuthor(String author) { 76 | this.author = author; 77 | } 78 | 79 | public void setType(String type) { 80 | this.type = type; 81 | } 82 | 83 | public void setWatchedNumber(String watchedNumber) { 84 | this.watchedNumber = watchedNumber; 85 | } 86 | 87 | public void setArticle(String article) { 88 | this.article = article; 89 | } 90 | 91 | public void setHeadPortrait(String headPortrait) { 92 | this.headPortrait = headPortrait; 93 | } 94 | 95 | public void setTopicReplyBeanList(List topicReplyBeanList) { 96 | this.topicReplyBeanList = topicReplyBeanList; 97 | } 98 | 99 | public void setStartNumber(String startNumber) { 100 | this.startNumber = startNumber; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Bean/TopicItemBean.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Bean; 2 | 3 | /** 4 | * Created by Yasic on 2016/5/18. 5 | */ 6 | public class TopicItemBean { 7 | private String title; 8 | private String type; 9 | private String icon; 10 | private String author; 11 | private String lastReply; 12 | private String totalReply; 13 | private String articleSequence; 14 | 15 | public TopicItemBean(String title, String type, String icon, String author, String lastReply, String totalReply, String articleSequence) { 16 | this.title = title; 17 | this.type = type; 18 | this.icon = icon; 19 | this.author = author; 20 | this.lastReply = lastReply; 21 | this.totalReply = totalReply; 22 | this.articleSequence = articleSequence; 23 | } 24 | 25 | public String getTitle() { 26 | return title; 27 | } 28 | 29 | public String getType() { 30 | return type; 31 | } 32 | 33 | public String getIcon() { 34 | return icon; 35 | } 36 | 37 | public String getAuthor() { 38 | return author; 39 | } 40 | 41 | public String getLastReply() { 42 | return lastReply; 43 | } 44 | 45 | public String getTotalReply() { 46 | return totalReply; 47 | } 48 | 49 | public String getArticleSequence() { 50 | return articleSequence; 51 | } 52 | 53 | public void setTitle(String title) { 54 | this.title = title; 55 | } 56 | 57 | public void setType(String type) { 58 | this.type = type; 59 | } 60 | 61 | public void setIcon(String icon) { 62 | this.icon = icon; 63 | } 64 | 65 | public void setAuthor(String author) { 66 | this.author = author; 67 | } 68 | 69 | public void setLastReply(String lastReply) { 70 | this.lastReply = lastReply; 71 | } 72 | 73 | public void setTotalReply(String totalReply) { 74 | this.totalReply = totalReply; 75 | } 76 | 77 | public void setArticleSequence(String articleSequence) { 78 | this.articleSequence = articleSequence; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Bean/TopicReplyBean.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Bean; 2 | 3 | /** 4 | * Created by Yasic on 2016/5/18. 5 | */ 6 | public class TopicReplyBean { 7 | private String author; 8 | private String headPortrait; 9 | private String replyInfo; 10 | private String publishTime; 11 | private String startNumber; 12 | 13 | public TopicReplyBean(String author, String headPortrait, String replyInfo, String publishTime, String startNumber) { 14 | this.author = author; 15 | this.headPortrait = headPortrait; 16 | this.replyInfo = replyInfo; 17 | this.publishTime = publishTime; 18 | this.startNumber = startNumber; 19 | } 20 | 21 | public String getAuthor() { 22 | return author; 23 | } 24 | 25 | public String getHeadPortrait() { 26 | return headPortrait; 27 | } 28 | 29 | public String getReplyInfo() { 30 | return replyInfo; 31 | } 32 | 33 | public String getPublishTime() { 34 | return publishTime; 35 | } 36 | 37 | public String getStartNumber() { 38 | return startNumber; 39 | } 40 | 41 | public void setAuthor(String author) { 42 | this.author = author; 43 | } 44 | 45 | public void setHeadPortrait(String headPortrait) { 46 | this.headPortrait = headPortrait; 47 | } 48 | 49 | public void setReplyInfo(String replyInfo) { 50 | this.replyInfo = replyInfo; 51 | } 52 | 53 | public void setPublishTime(String publishTime) { 54 | this.publishTime = publishTime; 55 | } 56 | 57 | public void setStartNumber(String startNumber) { 58 | this.startNumber = startNumber; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode; 2 | 3 | import android.graphics.Camera; 4 | import android.os.Bundle; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.support.v7.widget.Toolbar; 8 | import android.view.Menu; 9 | import android.view.MenuItem; 10 | import android.view.SurfaceHolder; 11 | import android.view.SurfaceView; 12 | import android.view.View; 13 | 14 | public class MainActivity extends AppCompatActivity { 15 | private Camera camera; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_main); 21 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 22 | setSupportActionBar(toolbar); 23 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 24 | SurfaceView surfaceView = (SurfaceView)findViewById(R.id.sfv_camera); 25 | surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 26 | surfaceView.getHolder().setKeepScreenOn(true); 27 | surfaceView.getHolder().setFixedSize(176, 144); 28 | 29 | assert fab != null; 30 | fab.setOnClickListener(new View.OnClickListener() { 31 | @Override 32 | public void onClick(View view) { 33 | /*Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 34 | .setAction("Action", null).show();*/ 35 | 36 | } 37 | }); 38 | } 39 | 40 | public int sum(int a, int b){ 41 | return a + b; 42 | } 43 | 44 | @Override 45 | public boolean onCreateOptionsMenu(Menu menu) { 46 | // Inflate the menu; this adds items to the action bar if it is present. 47 | getMenuInflater().inflate(R.menu.menu_main, menu); 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean onOptionsItemSelected(MenuItem item) { 53 | // Handle action bar item clicks here. The action bar will 54 | // automatically handle clicks on the Home/Up button, so long 55 | // as you specify a parent activity in AndroidManifest.xml. 56 | int id = item.getItemId(); 57 | 58 | //noinspection SimplifiableIfStatement 59 | if (id == R.id.action_settings) { 60 | return true; 61 | } 62 | 63 | return super.onOptionsItemSelected(item); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Model/ITopicModel.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Model; 2 | 3 | import com.yasic.diycode.Bean.CallbackBean; 4 | 5 | /** 6 | * Created by Yasic on 2016/5/18. 7 | */ 8 | public interface ITopicModel { 9 | CallbackBean getTopicList(String page); 10 | CallbackBean getTopicDetail(String topicSequence); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Model/TopicModel.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Model; 2 | 3 | import android.util.Log; 4 | 5 | import com.squareup.okhttp.Request; 6 | import com.squareup.okhttp.Response; 7 | import com.yasic.diycode.Bean.CallbackBean; 8 | import com.yasic.diycode.Bean.TopicDetailBean; 9 | import com.yasic.diycode.Bean.TopicItemBean; 10 | import com.yasic.diycode.Bean.TopicReplyBean; 11 | import com.yasic.diycode.Util.OkhttpUtil; 12 | 13 | import org.jsoup.Jsoup; 14 | import org.jsoup.nodes.Document; 15 | import org.jsoup.nodes.Element; 16 | import org.jsoup.select.Elements; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | /** 22 | * Created by Yasic on 2016/5/18. 23 | */ 24 | public class TopicModel implements ITopicModel { 25 | 26 | @Override 27 | public CallbackBean getTopicList(String page) { 28 | OkhttpUtil okhttpUtil = OkhttpUtil.getInstance(); 29 | final Request request = new Request.Builder().url("http://diycode.cc/?page=" + page).build(); 30 | try { 31 | List topicItemBeanList = new ArrayList<>(); 32 | String title, type, author, lastReply, totalReply, icon, articleSequense; 33 | Response response = okhttpUtil.okHttpClient.newCall(request).execute(); 34 | Document document = Jsoup.parse(response.body().string()); 35 | Element mainElement = document.getElementById("main"); 36 | Elements rowElements = mainElement.getElementsByClass("row"); 37 | Elements colmdElements = rowElements.get(0).getElementsByClass("col-md-9"); 38 | Elements panelBodyElements = colmdElements.get(0).getElementsByClass("panel-body"); 39 | Elements articleElements = panelBodyElements.get(0).select("div.topic"); 40 | for (int i = 0; i < articleElements.size(); i++){ 41 | articleSequense = articleElements.get(i).className(); 42 | String[] temp = articleSequense.split(" "); 43 | articleSequense = temp[2]; 44 | temp = articleSequense.split("-"); 45 | articleSequense = temp[1]; 46 | title = articleElements.get(i).select("div.infos").get(0).select("div.title").get(0).getElementsByTag("a").text(); 47 | type = articleElements.get(i).getElementsByClass("info").get(0).getElementsByClass("node").get(0).text(); 48 | author = articleElements.get(i).getElementsByClass("info").get(0).getElementsByClass("hacknews_clear").get(0).text(); 49 | lastReply = "最后由" + articleElements.get(i).getElementsByClass("info").get(0).getElementsByClass("hidden-mobile").get(0).getElementsByTag("a").text() + " " 50 | + articleElements.get(i).getElementsByClass("info").get(0).getElementsByClass("hidden-mobile").get(0).getElementsByTag("abbr").text() + "回复"; 51 | totalReply = articleElements.get(i).select("div.count").get(0).getElementsByTag("a").text(); 52 | if (totalReply == ""){ 53 | totalReply = "0"; 54 | } 55 | icon = articleElements.get(0).select("div.avatar").get(0).getElementsByClass("hacknews_clear").get(0).getElementsByTag("img").get(0).attr("src"); 56 | topicItemBeanList.add(new TopicItemBean(title, type, icon, author, lastReply, totalReply, articleSequense)); 57 | } 58 | CallbackBean> callbackBean = new CallbackBean<>("0", "", topicItemBeanList); 59 | return callbackBean; 60 | } 61 | catch (Exception e){ 62 | CallbackBean> callbackBean = new CallbackBean<>("1", e.getMessage(), null); 63 | Log.i("Exception", e.getMessage()); 64 | return callbackBean; 65 | } 66 | } 67 | 68 | @Override 69 | public CallbackBean getTopicDetail(String topicSequence) { 70 | OkhttpUtil okhttpUtil = OkhttpUtil.getInstance(); 71 | final Request request = new Request.Builder().url("http://diycode.cc/topics/" + topicSequence).build(); 72 | try { 73 | String title; 74 | String publishTime; 75 | String author; 76 | String type; 77 | //// TODO: 2016/5/19 there is some problems when get watchedNumber 78 | String watchedNumber = ""; 79 | String article; 80 | String headPortrait; 81 | String startNumber; 82 | List topicReplyBeanList = new ArrayList<>(); 83 | Response response = okhttpUtil.okHttpClient.newCall(request).execute(); 84 | Document document = Jsoup.parse(response.body().string()); 85 | Element mainElement = document.getElementById("main"); 86 | Elements rowElements = mainElement.getElementsByClass("row"); 87 | Elements colmdElements = rowElements.get(0).getElementsByClass("col-md-9"); 88 | Elements topicDetail = colmdElements.get(0).select("div.topic-detail"); 89 | Elements panelHeading = topicDetail.get(0).select("div.panel-heading"); 90 | Elements mediaBody = panelHeading.get(0).getElementsByClass("media-body"); 91 | Elements mediaHeading = mediaBody.get(0).select("h1.media-heading"); 92 | title = mediaHeading.text(); 93 | 94 | Elements info = mediaBody.get(0).getElementsByClass("info"); 95 | Elements node = info.get(0).getElementsByClass("node"); 96 | type = node.get(0).text(); 97 | 98 | publishTime = info.get(0).getElementsByClass("timeago").attr("title"); 99 | 100 | Elements hacknewsClear = info.get(0).select("a[data-author=true]"); 101 | author = hacknewsClear.text(); 102 | 103 | Elements avatar = panelHeading.select("div.avatar"); 104 | headPortrait = avatar.get(0).getElementsByClass("hacknews_clear").get(0).getElementsByTag("img").get(0).attr("src"); 105 | 106 | Elements panelBody = topicDetail.get(0).select("div.panel-body"); 107 | Elements articleElement = panelBody.get(0).select("article"); 108 | article = articleElement.html(); 109 | 110 | startNumber = ""; 111 | //// TODO: 2016/5/19 startNumber must be got when login in 112 | /*startNumber = topicDetail.get(0).select("div.panel-footer").get(0). 113 | getElementsByClass("opts").get(0). 114 | select("a.likeable").attr("data-count"); 115 | Log.i("startNumber", startNumber);*/ 116 | if (colmdElements.get(0).getElementsByClass("no-result").size() == 0){ 117 | topicReplyBeanList = getTopicReplyList(colmdElements, topicReplyBeanList); 118 | } 119 | 120 | TopicDetailBean topicDetailBean = new TopicDetailBean(title, publishTime, author, 121 | type, watchedNumber, article, headPortrait, startNumber, topicReplyBeanList); 122 | 123 | CallbackBean topicDetailBeanCallbackBean = new CallbackBean<>("0", "", topicDetailBean); 124 | return topicDetailBeanCallbackBean; 125 | } 126 | catch (Exception e){ 127 | Log.i("Exception", e.getMessage()); 128 | CallbackBean errorCallBackBean = new CallbackBean<>("1", e.getMessage(), null); 129 | return errorCallBackBean; 130 | } 131 | } 132 | 133 | private List getTopicReplyList(Elements colmdElements, List topicReplyBeanList){ 134 | String author; 135 | String headPortrait; 136 | String publishTime; 137 | String replyInfo; 138 | String startNumber; 139 | Element replies = colmdElements.get(0).getElementById("replies"); 140 | Elements itemPanelBody = replies.select("div.items"); 141 | Elements replyElements = itemPanelBody.get(0).getElementsByClass("reply"); 142 | Elements avatar; 143 | Elements hacknews_clear; 144 | Elements infos; 145 | Elements info; 146 | Elements name; 147 | Elements time; 148 | Elements markdown; 149 | Elements optsPullRight; 150 | Elements likeAble; 151 | Elements faThumbsUp; 152 | try { 153 | for (int i = 0; i < replyElements.size(); i++){ 154 | avatar = replyElements.get(i).select("div.avatar"); 155 | hacknews_clear = avatar.get(0).getElementsByClass("hacknews_clear"); 156 | headPortrait = hacknews_clear.get(0).select("img.media-object").attr("src"); 157 | 158 | infos = replyElements.get(i).select("div.infos"); 159 | info = infos.get(0).select("div.info"); 160 | name = info.get(0).getElementsByClass("name"); 161 | author = name.get(0).getElementsByClass("hacknews_clear").text(); 162 | 163 | time = info.get(0).getElementsByClass("time"); 164 | publishTime = time.get(0).getElementsByTag("abbr").attr("title"); 165 | 166 | markdown = infos.get(0).getElementsByClass("markdown"); 167 | replyInfo = markdown.text(); 168 | 169 | 170 | optsPullRight = info.get(0).select("span.opts"); 171 | likeAble = optsPullRight.get(0).select("a.likeable"); 172 | startNumber = likeAble.attr("data-count"); 173 | topicReplyBeanList.add(new TopicReplyBean(author, headPortrait, replyInfo, publishTime,startNumber)); 174 | } 175 | return topicReplyBeanList; 176 | }catch (Exception e){ 177 | return null; 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/BasePresenterActivity.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | import com.facebook.drawee.backends.pipeline.Fresco; 7 | import com.yasic.diycode.View.BaseViewInterface; 8 | 9 | /** 10 | * Created by Yasic on 2016/3/18. 11 | */ 12 | public abstract class BasePresenterActivity extends AppCompatActivity { 13 | protected BVI BVIView; 14 | 15 | @Override 16 | protected final void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | try { 19 | BVIView = getBVIClass().newInstance(); 20 | BVIView.init(getLayoutInflater(), null); 21 | Fresco.initialize(this); 22 | setContentView(BVIView.getView()); 23 | onBindBVI(); 24 | } catch (InstantiationException e) { 25 | e.printStackTrace(); 26 | } catch (IllegalAccessException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | @Override 32 | protected final void onDestroy() { 33 | onDestroyBVI(); 34 | BVIView = null; 35 | super.onDestroy(); 36 | } 37 | 38 | protected abstract Class getBVIClass(); 39 | 40 | protected void onBindBVI(){}; 41 | 42 | protected void onDestroyBVI() {}; 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/BasePresenterFragment.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.facebook.drawee.backends.pipeline.Fresco; 11 | import com.yasic.diycode.View.BaseViewInterface; 12 | 13 | /** 14 | * Created by ESIR on 2016/3/18. 15 | */ 16 | public abstract class BasePresenterFragment extends Fragment { 17 | protected BVI BVIView; 18 | 19 | @Override 20 | public void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | Fresco.initialize(getActivity()); 23 | } 24 | 25 | @Override 26 | public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 27 | View view = null; 28 | try { 29 | BVIView = getBVIClass().newInstance(); 30 | BVIView.init(inflater, container); 31 | onBindBVI(); 32 | view = BVIView.getView(); 33 | } catch (java.lang.InstantiationException e) { 34 | e.printStackTrace(); 35 | } catch (IllegalAccessException e) { 36 | e.printStackTrace(); 37 | } 38 | return view; 39 | } 40 | 41 | @Override 42 | public final void onDestroyView() { 43 | onDestroyBVI(); 44 | BVIView = null; 45 | super.onDestroyView(); 46 | } 47 | 48 | protected void onDestroyBVI() {}; 49 | 50 | protected void onBindBVI(){}; 51 | 52 | protected abstract Class getBVIClass(); 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/ContainerPresenter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | import android.support.v7.widget.Toolbar; 4 | 5 | import com.yasic.diycode.R; 6 | import com.yasic.diycode.View.ContainerView; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by Yasic on 2016/5/18. 13 | */ 14 | public class ContainerPresenter extends BasePresenterActivity { 15 | @Override 16 | protected void onBindBVI() { 17 | setSupportActionBar((Toolbar) BVIView.getView().findViewById(R.id.tb_container)); 18 | BVIView.setPresenter(this); 19 | List tabTitleList = new ArrayList<>(); 20 | tabTitleList.add("社区"); 21 | tabTitleList.add("个人主页"); 22 | tabTitleList.add("设置"); 23 | List basePresenterFragmentList = new ArrayList<>(); 24 | basePresenterFragmentList.add(new TopicListPresenter()); 25 | basePresenterFragmentList.add(new PersonalInfoPresenter()); 26 | basePresenterFragmentList.add(new SettingPresenter()); 27 | BVIView.setViewPagerAndTablayout(tabTitleList, basePresenterFragmentList); 28 | } 29 | 30 | 31 | @Override 32 | protected Class getBVIClass() { 33 | return ContainerView.class; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/PersonalInfoPresenter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | import com.yasic.diycode.View.PersonalInfoView; 4 | 5 | /** 6 | * Created by Yasic on 2016/5/18. 7 | */ 8 | public class PersonalInfoPresenter extends BasePresenterFragment { 9 | @Override 10 | protected Class getBVIClass() { 11 | return PersonalInfoView.class; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/SettingPresenter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | import com.yasic.diycode.View.Settingview; 4 | 5 | /** 6 | * Created by Yasic on 2016/5/18. 7 | */ 8 | public class SettingPresenter extends BasePresenterFragment { 9 | @Override 10 | protected Class getBVIClass() { 11 | return Settingview.class; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/TopicDetailPresenter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | import android.util.Log; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewTreeObserver; 7 | import android.widget.TextView; 8 | import android.widget.Toast; 9 | 10 | import com.yasic.diycode.Adapter.TopicDetailAdapter; 11 | import com.yasic.diycode.Bean.CallbackBean; 12 | import com.yasic.diycode.Bean.TopicDetailBean; 13 | import com.yasic.diycode.Model.TopicModel; 14 | import com.yasic.diycode.R; 15 | import com.yasic.diycode.View.TopicDetailView; 16 | 17 | import rx.Observable; 18 | import rx.Subscriber; 19 | import rx.android.schedulers.AndroidSchedulers; 20 | import rx.functions.Action1; 21 | import rx.schedulers.Schedulers; 22 | 23 | /** 24 | * Created by Yasic on 2016/5/19. 25 | */ 26 | public class TopicDetailPresenter extends BasePresenterActivity{ 27 | private TopicModel topicModel = new TopicModel(); 28 | private String SEQUENCE; 29 | private TopicDetailAdapter topicDetailAdapter; 30 | @Override 31 | protected void onBindBVI() { 32 | BVIView.setPresenter(this); 33 | BVIView.initRvTopicList(this); 34 | BVIView.getView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 35 | @Override 36 | public void onGlobalLayout() { 37 | BVIView.getView().getViewTreeObserver().removeGlobalOnLayoutListener(this); 38 | BVIView.setSwipeRefreshLayout(true); 39 | } 40 | }); 41 | SEQUENCE = getIntent().getExtras().getString("SEQUENCE"); 42 | getTopicDetail(); 43 | } 44 | 45 | public void getTopicDetail() { 46 | Observable.create(new Observable.OnSubscribe>() { 47 | @Override 48 | public void call(Subscriber> subscriber) { 49 | CallbackBean callbackBean = topicModel.getTopicDetail(SEQUENCE); 50 | subscriber.onNext(callbackBean); 51 | subscriber.onCompleted(); 52 | } 53 | }) 54 | .subscribeOn(Schedulers.io()) 55 | .observeOn(AndroidSchedulers.mainThread()) 56 | .subscribe(new Action1>() { 57 | @Override 58 | public void call(CallbackBean callbackBean) { 59 | if (callbackBean.getCode().equals("0")) { 60 | TopicDetailBean topicDetailBean = callbackBean.getResponse(); 61 | View topicDetailHeader = LayoutInflater.from(getApplicationContext()) 62 | .inflate(R.layout.content_headoftopicdetail, BVIView.getRvTopicDetail(), false); 63 | TextView tvTitle = (TextView) topicDetailHeader.findViewById(R.id.tv_Title); 64 | TextView tvType = (TextView) topicDetailHeader.findViewById(R.id.tv_Type); 65 | TextView tvAuthor = (TextView) topicDetailHeader.findViewById(R.id.tv_Author); 66 | TextView tvTopicContent = (TextView) topicDetailHeader.findViewById(R.id.tv_TopicContent); 67 | tvTitle.setText(topicDetailBean.getTitle()); 68 | tvType.setText(topicDetailBean.getType()); 69 | tvAuthor.setText(topicDetailBean.getAuthor()); 70 | tvTopicContent.setText(topicDetailBean.getArticle()); 71 | if (topicDetailAdapter == null){ 72 | topicDetailAdapter = new TopicDetailAdapter(getApplicationContext(), topicDetailBean); 73 | BVIView.getRvTopicDetail().setAdapter(topicDetailAdapter); 74 | topicDetailAdapter.setHeaderView(topicDetailHeader); 75 | } 76 | else { 77 | topicDetailAdapter.refreshData(topicDetailBean); 78 | } 79 | } else { 80 | if (callbackBean.getErrorMessage() == null || callbackBean.getErrorMessage().equals("")) { 81 | Toast.makeText(getApplicationContext(), "貌似网络出现了错误?", Toast.LENGTH_LONG).show(); 82 | } 83 | Toast.makeText(getApplicationContext(), callbackBean.getErrorMessage(), Toast.LENGTH_LONG).show(); 84 | } 85 | BVIView.setSwipeRefreshLayout(false); 86 | } 87 | }, new Action1() { 88 | @Override 89 | public void call(Throwable throwable) { 90 | Log.i("throwable",throwable.getMessage()); 91 | BVIView.setSwipeRefreshLayout(false); 92 | } 93 | }); 94 | } 95 | 96 | @Override 97 | protected Class getBVIClass() { 98 | return TopicDetailView.class; 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Presenter/TopicListPresenter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Presenter; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.view.ViewTreeObserver; 6 | import android.widget.Toast; 7 | 8 | import com.yasic.diycode.Bean.CallbackBean; 9 | import com.yasic.diycode.Bean.TopicItemBean; 10 | import com.yasic.diycode.Model.TopicModel; 11 | import com.yasic.diycode.View.TopicListView; 12 | 13 | import java.util.List; 14 | 15 | import rx.Observable; 16 | import rx.Subscriber; 17 | import rx.android.schedulers.AndroidSchedulers; 18 | import rx.functions.Action1; 19 | import rx.schedulers.Schedulers; 20 | 21 | /** 22 | * Created by Yasic on 2016/5/18. 23 | */ 24 | public class TopicListPresenter extends BasePresenterFragment{ 25 | private TopicModel topicModel = new TopicModel(); 26 | @Override 27 | protected void onBindBVI() { 28 | BVIView.setPresenter(this); 29 | BVIView.initRvTopicList(getActivity().getApplicationContext()); 30 | BVIView.getView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 31 | @Override 32 | public void onGlobalLayout() { 33 | BVIView.getView().getViewTreeObserver().removeGlobalOnLayoutListener(this); 34 | BVIView.setProgressBarVisible(); 35 | } 36 | }); 37 | getTopicList(1); 38 | } 39 | 40 | public Object getTopicList(final int page) { 41 | Observable.create(new Observable.OnSubscribe>>() { 42 | @Override 43 | public void call(Subscriber>> subscriber) { 44 | CallbackBean> callbackBean = topicModel.getTopicList(1+""); 45 | subscriber.onNext(callbackBean); 46 | subscriber.onCompleted(); 47 | } 48 | }) 49 | .subscribeOn(Schedulers.io()) 50 | .observeOn(AndroidSchedulers.mainThread()) 51 | .subscribe(new Action1>>() { 52 | @Override 53 | public void call(CallbackBean> callbackBean) { 54 | if (callbackBean.getCode().equals("0")) { 55 | BVIView.setRvTopicList(getActivity().getApplicationContext(), callbackBean.getResponse()); 56 | } else { 57 | if (callbackBean.getErrorMessage() == null || callbackBean.getErrorMessage().equals("")) { 58 | Toast.makeText(getContext(), "貌似网络出现了错误?", Toast.LENGTH_LONG).show(); 59 | } 60 | Toast.makeText(getContext(), callbackBean.getErrorMessage(), Toast.LENGTH_LONG).show(); 61 | } 62 | BVIView.setProgressBarGone(); 63 | } 64 | }, new Action1() { 65 | @Override 66 | public void call(Throwable throwable) { 67 | try{ 68 | BVIView.setProgressBarGone(); 69 | }catch (Exception e){ 70 | 71 | } 72 | } 73 | }); 74 | return null; 75 | } 76 | 77 | public void startTopicDetailPresenter(final String sequence){ 78 | Intent intent = new Intent(getActivity(), TopicDetailPresenter.class); 79 | Bundle bundle = new Bundle(); 80 | bundle.putString("SEQUENCE", sequence); 81 | 82 | intent.putExtras(bundle); 83 | startActivity(intent); 84 | /*Observable.create(new Observable.OnSubscribe>>() { 85 | @Override 86 | public void call(Subscriber>> subscriber) { 87 | CallbackBean> callbackBean = topicModel.getTopicDetail(sequence); 88 | subscriber.onNext(callbackBean); 89 | subscriber.onCompleted(); 90 | } 91 | }) 92 | .subscribeOn(Schedulers.io()) 93 | .observeOn(AndroidSchedulers.mainThread()) 94 | .subscribe(new Action1>>() { 95 | @Override 96 | public void call(CallbackBean> callbackBean) { 97 | if (callbackBean.getCode().equals("0")) { 98 | } else { 99 | if (callbackBean.getErrorMessage() == null || callbackBean.getErrorMessage().equals("")) { 100 | Toast.makeText(getContext(), "貌似网络出现了错误?", Toast.LENGTH_LONG).show(); 101 | } 102 | Toast.makeText(getContext(), callbackBean.getErrorMessage(), Toast.LENGTH_LONG).show(); 103 | } 104 | } 105 | }, new Action1() { 106 | @Override 107 | public void call(Throwable throwable) { 108 | Log.i("throwable",throwable.getMessage()); 109 | } 110 | });*/ 111 | } 112 | 113 | @Override 114 | protected Class getBVIClass() { 115 | return TopicListView.class; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Util/OkhttpUtil.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Util; 2 | 3 | import com.squareup.okhttp.OkHttpClient; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * Created by ESIR on 2016/3/17. 9 | */ 10 | public class OkhttpUtil { 11 | private static OkhttpUtil okhttpUtil = null; 12 | public OkHttpClient okHttpClient = null; 13 | private OkhttpUtil(){ 14 | init(); 15 | } 16 | 17 | private void init(){ 18 | okHttpClient = new OkHttpClient(); 19 | okHttpClient.setConnectTimeout(10, TimeUnit.SECONDS); 20 | okHttpClient.setReadTimeout(10, TimeUnit.SECONDS); 21 | } 22 | 23 | public static OkhttpUtil getInstance(){ 24 | if(okhttpUtil == null){ 25 | synchronized (OkhttpUtil.class){ 26 | if(okhttpUtil == null){ 27 | okhttpUtil = new OkhttpUtil(); 28 | } 29 | } 30 | } 31 | return okhttpUtil; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/Util/UrlImageGetter.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.Util; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.text.Html; 5 | 6 | /** 7 | * Created by Yasic on 2016/5/24. 8 | */ 9 | public class UrlImageGetter implements Html.ImageGetter { 10 | 11 | @Override 12 | public Drawable getDrawable(String source) { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/View/BaseViewInterface.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.View; 2 | 3 | import android.app.Activity; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | /** 10 | * Created by Yasic on 2016/3/17. 11 | */ 12 | public interface BaseViewInterface { 13 | void init(LayoutInflater inflater, ViewGroup container); 14 | View getView(); 15 | void setPresenter(T t); 16 | void setPresenter(E e); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/View/ContainerView.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.View; 2 | 3 | import android.support.design.widget.TabLayout; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.view.ViewPager; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.yasic.diycode.Adapter.ViewPagerMainInterfaceAdapter; 11 | import com.yasic.diycode.Presenter.BasePresenterFragment; 12 | import com.yasic.diycode.Presenter.ContainerPresenter; 13 | import com.yasic.diycode.R; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * Created by Yasic on 2016/5/18. 19 | */ 20 | public class ContainerView implements BaseViewInterface { 21 | private View view; 22 | private ViewPager viewPager; 23 | private TabLayout tabLayout; 24 | private ContainerPresenter containerPresenter; 25 | @Override 26 | public void init(LayoutInflater inflater, ViewGroup container) { 27 | view = inflater.inflate(R.layout.activity_container, container, false); 28 | viewPager = (ViewPager) view.findViewById(R.id.vp_Container); 29 | tabLayout = (TabLayout) view.findViewById(R.id.tl_Container); 30 | } 31 | 32 | @Override 33 | public View getView() { 34 | return view; 35 | } 36 | 37 | public void setViewPagerAndTablayout(List tabTitleList, List basePresenterFragmentList) { 38 | viewPager.setAdapter(new ViewPagerMainInterfaceAdapter<>( 39 | containerPresenter.getSupportFragmentManager(), 40 | tabTitleList, 41 | basePresenterFragmentList)); 42 | viewPager.setOffscreenPageLimit(3); 43 | tabLayout.setupWithViewPager(viewPager); 44 | tabLayout.setTabMode(TabLayout.MODE_FIXED); 45 | containerPresenter.getSupportFragmentManager().beginTransaction().commit(); 46 | } 47 | 48 | @Override 49 | public void setPresenter(ContainerPresenter containerPresenter) { 50 | this.containerPresenter = containerPresenter; 51 | } 52 | 53 | @Override 54 | public void setPresenter(Fragment fragment) { 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/View/PersonalInfoView.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.View; 2 | 3 | import android.app.Activity; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.yasic.diycode.Presenter.PersonalInfoPresenter; 9 | 10 | /** 11 | * Created by Yasic on 2016/5/18. 12 | */ 13 | public class PersonalInfoView implements BaseViewInterface { 14 | @Override 15 | public void init(LayoutInflater inflater, ViewGroup container) { 16 | 17 | } 18 | 19 | @Override 20 | public View getView() { 21 | return null; 22 | } 23 | 24 | @Override 25 | public void setPresenter(Activity activity) { 26 | 27 | } 28 | 29 | @Override 30 | public void setPresenter(PersonalInfoPresenter personalInfoPresenter) { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/View/Settingview.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.View; 2 | 3 | import android.app.Activity; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.yasic.diycode.Presenter.SettingPresenter; 9 | 10 | /** 11 | * Created by Yasic on 2016/5/18. 12 | */ 13 | public class Settingview implements BaseViewInterface { 14 | @Override 15 | public void init(LayoutInflater inflater, ViewGroup container) { 16 | 17 | } 18 | 19 | @Override 20 | public View getView() { 21 | return null; 22 | } 23 | 24 | @Override 25 | public void setPresenter(Activity activity) { 26 | 27 | } 28 | 29 | @Override 30 | public void setPresenter(SettingPresenter settingPresenter) { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/View/TopicDetailView.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.View; 2 | 3 | import android.content.Context; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.widget.SwipeRefreshLayout; 6 | import android.support.v7.widget.DefaultItemAnimator; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | 13 | import com.yasic.diycode.Presenter.TopicDetailPresenter; 14 | import com.yasic.diycode.R; 15 | 16 | /** 17 | * Created by Yasic on 2016/5/19. 18 | */ 19 | public class TopicDetailView implements BaseViewInterface { 20 | private View view; 21 | private TopicDetailPresenter topicDetailPresenter; 22 | private RecyclerView rvTopicDetail; 23 | private SwipeRefreshLayout swipeRefreshLayout; 24 | @Override 25 | public void init(LayoutInflater inflater, ViewGroup container) { 26 | view = inflater.inflate(R.layout.activity_topicdetail, container, false); 27 | rvTopicDetail = (RecyclerView) view.findViewById(R.id.rv_TopicDetail); 28 | swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.srl_RefreshLayout); 29 | swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 30 | @Override 31 | public void onRefresh() { 32 | topicDetailPresenter.getTopicDetail(); 33 | } 34 | }); 35 | } 36 | 37 | public void setSwipeRefreshLayout(boolean isRefreshing){ 38 | swipeRefreshLayout.setRefreshing(isRefreshing); 39 | } 40 | 41 | public void initRvTopicList(Context context){ 42 | rvTopicDetail.setLayoutManager(new LinearLayoutManager(context)); 43 | rvTopicDetail.setItemAnimator(new DefaultItemAnimator()); 44 | } 45 | 46 | public RecyclerView getRvTopicDetail(){ 47 | return rvTopicDetail; 48 | } 49 | 50 | @Override 51 | public View getView() { 52 | return view; 53 | } 54 | 55 | @Override 56 | public void setPresenter(TopicDetailPresenter topicDetailPresenter) { 57 | this.topicDetailPresenter = topicDetailPresenter; 58 | } 59 | 60 | @Override 61 | public void setPresenter(Fragment fragment) { 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/yasic/diycode/View/TopicListView.java: -------------------------------------------------------------------------------- 1 | package com.yasic.diycode.View; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.support.v4.content.ContextCompat; 6 | import android.support.v4.widget.SwipeRefreshLayout; 7 | import android.support.v7.widget.DefaultItemAnimator; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | 14 | import com.yasic.diycode.Adapter.TopicListAdapter; 15 | import com.yasic.diycode.Bean.TopicItemBean; 16 | import com.yasic.diycode.Presenter.TopicListPresenter; 17 | import com.yasic.diycode.R; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * Created by Yasic on 2016/5/18. 23 | */ 24 | public class TopicListView implements BaseViewInterface{ 25 | private View view; 26 | private RecyclerView rvTopicList; 27 | private SwipeRefreshLayout swipeRefreshLayout; 28 | private TopicListPresenter topicListPresenter; 29 | @Override 30 | public void init(LayoutInflater inflater, ViewGroup container) { 31 | view = inflater.inflate(R.layout.fragment_topiclist, container, false); 32 | rvTopicList = (RecyclerView) view.findViewById(R.id.rv_TopicList); 33 | swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.srl_RefreshLayout); 34 | swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 35 | @Override 36 | public void onRefresh() { 37 | topicListPresenter.getTopicList(1); 38 | } 39 | }); 40 | } 41 | 42 | public void setRvTopicList(Context context, final List topicItemBeanList){ 43 | final TopicListAdapter topicListAdapter = new TopicListAdapter(context, topicItemBeanList); 44 | topicListAdapter.setOnItemClickListener(new TopicListAdapter.OnItemClickListener() { 45 | @Override 46 | public void onItemClick(View v, int position) { 47 | topicListPresenter.startTopicDetailPresenter(topicItemBeanList.get(position).getArticleSequence()); 48 | } 49 | 50 | @Override 51 | public void onItemLongCick(View v, int position) { 52 | 53 | } 54 | }); 55 | rvTopicList.setAdapter(topicListAdapter); 56 | } 57 | 58 | public void setProgressBarVisible(){ 59 | swipeRefreshLayout.setRefreshing(true); 60 | } 61 | 62 | public void setProgressBarGone(){ 63 | swipeRefreshLayout.setRefreshing(false); 64 | } 65 | 66 | public void initRvTopicList(Context context){ 67 | rvTopicList.setLayoutManager(new LinearLayoutManager(context)); 68 | rvTopicList.setItemAnimator(new DefaultItemAnimator()); 69 | } 70 | 71 | @Override 72 | public View getView() { 73 | return view; 74 | } 75 | 76 | @Override 77 | public void setPresenter(Activity activity) { 78 | 79 | } 80 | 81 | @Override 82 | public void setPresenter(TopicListPresenter topicListPresenter) { 83 | this.topicListPresenter = topicListPresenter; 84 | swipeRefreshLayout.setColorSchemeColors( 85 | ContextCompat.getColor(topicListPresenter.getActivity(), R.color.colorPrimary), 86 | ContextCompat.getColor(topicListPresenter.getActivity(), R.color.colorAccent), 87 | ContextCompat.getColor(topicListPresenter.getActivity(), R.color.colorPrimaryBlue)); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_reply_blue_a400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-hdpi/ic_reply_blue_a400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_star_border_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-hdpi/ic_star_border_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_star_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-hdpi/ic_star_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_reply_blue_a400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-mdpi/ic_reply_blue_a400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_star_border_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-mdpi/ic_star_border_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_star_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-mdpi/ic_star_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_reply_blue_a400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xhdpi/ic_reply_blue_a400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_star_border_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xhdpi/ic_star_border_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_star_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xhdpi/ic_star_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_reply_blue_a400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xxhdpi/ic_reply_blue_a400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_star_border_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xxhdpi/ic_star_border_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_star_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xxhdpi/ic_star_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_reply_blue_a400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xxxhdpi/ic_reply_blue_a400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_border_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xxxhdpi/ic_star_border_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_pink_400_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/drawable-xxxhdpi/ic_star_pink_400_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 27 | 28 | 32 | 36 | 37 | 38 | 39 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_topicdetail.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_comment.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 19 | 24 | 30 | 39 | 40 | 44 | 50 | 58 | 62 | 68 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_headoftopicdetail.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 19 | 26 | 29 | 36 | 37 | 41 | 51 | 59 | 60 | 71 | 72 | 78 | 88 | 89 | 90 | 94 | 100 | 101 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_topichead.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_topiclist.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_topiclist.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 21 | 24 | 31 | 32 | 36 | 46 | 54 | 55 | 58 | 65 | 66 | 67 | 73 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_topic.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_topic_detail.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yasic/DiyCodeForAndroid/1b7b2de4307c7c9fe56a06c53976d61d99c0cb07/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | #F7F8F3 7 | #000000 8 | #767676 9 | #545454 10 | #bababa 11 | #3399ff 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 16dp 6 | 180dp 7 | 16dp 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DiyCode 3 | Settings 4 | Topic 5 | 6 | "Material is the metaphor.\n\n" 7 | 8 | "A material metaphor is the unifying theory of a rationalized space and a system of motion." 9 | "The material is grounded in tactile reality, inspired by the study of paper and ink, yet " 10 | "technologically advanced and open to imagination and magic.\n" 11 | "Surfaces and edges of the material provide visual cues that are grounded in reality. The " 12 | "use of familiar tactile attributes helps users quickly understand affordances. Yet the " 13 | "flexibility of the material creates new affordances that supercede those in the physical " 14 | "world, without breaking the rules of physics.\n" 15 | "The fundamentals of light, surface, and movement are key to conveying how objects move, " 16 | "interact, and exist in space and in relation to each other. Realistic lighting shows " 17 | "seams, divides space, and indicates moving parts.\n\n" 18 | 19 | "Bold, graphic, intentional.\n\n" 20 | 21 | "The foundational elements of print based design typography, grids, space, scale, color, " 22 | "and use of imagery guide visual treatments. These elements do far more than please the " 23 | "eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge " 24 | "imagery, large scale typography, and intentional white space create a bold and graphic " 25 | "interface that immerse the user in the experience.\n" 26 | "An emphasis on user actions makes core functionality immediately apparent and provides " 27 | "waypoints for the user.\n\n" 28 | 29 | "Motion provides meaning.\n\n" 30 | 31 | "Motion respects and reinforces the user as the prime mover. Primary user actions are " 32 | "inflection points that initiate motion, transforming the whole design.\n" 33 | "All action takes place in a single environment. Objects are presented to the user without " 34 | "breaking the continuity of experience even as they transform and reorganize.\n" 35 | "Motion is meaningful and appropriate, serving to focus attention and maintain continuity. " 36 | "Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n" 37 | 38 | "3D world.\n\n" 39 | 40 | "The material environment is a 3D space, which means all objects have x, y, and z " 41 | "dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the " 42 | "positive z-axis extending towards the viewer. Every sheet of material occupies a single " 43 | "position along the z-axis and has a standard 1dp thickness.\n" 44 | "On the web, the z-axis is used for layering and not for perspective. The 3D world is " 45 | "emulated by manipulating the y-axis.\n\n" 46 | 47 | "Light and shadow.\n\n" 48 | 49 | "Within the material environment, virtual lights illuminate the scene. Key lights create " 50 | "directional shadows, while ambient light creates soft shadows from all angles.\n" 51 | "Shadows in the material environment are cast by these two light sources. In Android " 52 | "development, shadows occur when light sources are blocked by sheets of material at " 53 | "various positions along the z-axis. On the web, shadows are depicted by manipulating the " 54 | "y-axis only. The following example shows the card with a height of 6dp.\n\n" 55 | 56 | "Resting elevation.\n\n" 57 | 58 | "All material objects, regardless of size, have a resting elevation, or default elevation " 59 | "that does not change. If an object changes elevation, it should return to its resting " 60 | "elevation as soon as possible.\n\n" 61 | 62 | "Component elevations.\n\n" 63 | 64 | "The resting elevation for a component type is consistent across apps (e.g., FAB elevation " 65 | "does not vary from 6dp in one app to 16dp in another app).\n" 66 | "Components may have different resting elevations across platforms, depending on the depth " 67 | "of the environment (e.g., TV has a greater depth than mobile or desktop).\n\n" 68 | 69 | "Responsive elevation and dynamic elevation offsets.\n\n" 70 | 71 | "Some component types have responsive elevation, meaning they change elevation in response " 72 | "to user input (e.g., normal, focused, and pressed) or system events. These elevation " 73 | "changes are consistently implemented using dynamic elevation offsets.\n" 74 | "Dynamic elevation offsets are the goal elevation that a component moves towards, relative " 75 | "to the component’s resting state. They ensure that elevation changes are consistent " 76 | "across actions and component types. For example, all components that lift on press have " 77 | "the same elevation change relative to their resting elevation.\n" 78 | "Once the input event is completed or cancelled, the component will return to its resting " 79 | "elevation.\n\n" 80 | 81 | "Avoiding elevation interference.\n\n" 82 | 83 | "Components with responsive elevations may encounter other components as they move between " 84 | "their resting elevations and dynamic elevation offsets. Because material cannot pass " 85 | "through other material, components avoid interfering with one another any number of ways, " 86 | "whether on a per component basis or using the entire app layout.\n" 87 | "On a component level, components can move or be removed before they cause interference. " 88 | "For example, a floating action button (FAB) can disappear or move off screen before a " 89 | "user picks up a card, or it can move if a snackbar appears.\n" 90 | "On the layout level, design your app layout to minimize opportunities for interference. " 91 | "For example, position the FAB to one side of stream of a cards so the FAB won’t interfere " 92 | "when a user tries to pick up one of cards.\n\n" 93 | 94 | TopicDetail 95 | 96 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |