├── .github └── workflows │ └── android.yml ├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── dictionaries │ └── liuhuiliang.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── app-release.apk ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── demo │ │ └── redbook │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── demo │ │ │ ├── adapter │ │ │ └── note │ │ │ │ ├── CommentDelegate.java │ │ │ │ ├── ContentDelegate.java │ │ │ │ ├── HeadDelegate.java │ │ │ │ └── HomeAdapter.java │ │ │ ├── app │ │ │ └── App.java │ │ │ ├── data │ │ │ └── RedBookData.java │ │ │ ├── model │ │ │ ├── CommentModel.java │ │ │ ├── HomeModel.java │ │ │ ├── NoteModel.java │ │ │ ├── PictureModel.java │ │ │ ├── SizeModel.java │ │ │ └── UserModel.java │ │ │ ├── redbook │ │ │ └── MainActivity.java │ │ │ └── utils │ │ │ ├── PictureSize.java │ │ │ └── StatusBarUtils.java │ └── res │ │ ├── drawable-hdpi │ │ └── ic_note_bg.9.png │ │ ├── drawable-xxhdpi │ │ ├── common_head_btn_back.png │ │ ├── ic_default_head.png │ │ ├── ic_like_count_def.png │ │ ├── note_icon_comment.png │ │ ├── note_icon_fav_normal.png │ │ └── note_icon_like_normal.png │ │ ├── drawable │ │ └── sp_round.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── item_note_comment.xml │ │ ├── item_note_head.xml │ │ └── item_note_notes.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-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── demo │ └── redbook │ └── ExampleUnitTest.java ├── build.gradle ├── checkstyle.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── redbook.gif └── settings.gradle /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: set up JDK 1.8 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 1.8 20 | - name: Build with Gradle 21 | run: ./gradlew build 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.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/dictionaries/liuhuiliang.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Abstraction issuesJava 39 | 40 | 41 | Android 42 | 43 | 44 | Android > Lint > Accessibility 45 | 46 | 47 | Android > Lint > Correctness 48 | 49 | 50 | Android > Lint > Correctness > Messages 51 | 52 | 53 | Android > Lint > Internationalization 54 | 55 | 56 | Android > Lint > Performance 57 | 58 | 59 | Android > Lint > Security 60 | 61 | 62 | Android > Lint > Usability 63 | 64 | 65 | Android > Lint > Usability > Icons 66 | 67 | 68 | Assignment issuesGroovy 69 | 70 | 71 | Assignment issuesJava 72 | 73 | 74 | Bitwise operation issuesJava 75 | 76 | 77 | C/C++ 78 | 79 | 80 | Class structureJava 81 | 82 | 83 | Code style issuesJava 84 | 85 | 86 | Control FlowGroovy 87 | 88 | 89 | Control flow issuesJava 90 | 91 | 92 | Data flow analysisC/C++ 93 | 94 | 95 | GPath inspectionsGroovy 96 | 97 | 98 | General 99 | 100 | 101 | GeneralC/C++ 102 | 103 | 104 | GeneralJava 105 | 106 | 107 | Groovy 108 | 109 | 110 | HTML 111 | 112 | 113 | Initialization issuesJava 114 | 115 | 116 | Internationalization issuesJava 117 | 118 | 119 | J2ME issuesJava 120 | 121 | 122 | JUnit issuesJava 123 | 124 | 125 | Java 126 | 127 | 128 | Java language level issuesJava 129 | 130 | 131 | Java language level migration aidsJava 132 | 133 | 134 | Javadoc issuesJava 135 | 136 | 137 | Logging issuesJava 138 | 139 | 140 | Memory issuesJava 141 | 142 | 143 | Naming ConventionsGroovy 144 | 145 | 146 | Naming conventionsJava 147 | 148 | 149 | Numeric issuesJava 150 | 151 | 152 | Performance issuesJava 153 | 154 | 155 | Portability issuesJava 156 | 157 | 158 | Potentially confusing code constructsGroovy 159 | 160 | 161 | Probable bugsGroovy 162 | 163 | 164 | Probable bugsJava 165 | 166 | 167 | Properties Files 168 | 169 | 170 | RELAX NG 171 | 172 | 173 | Security issuesJava 174 | 175 | 176 | TestNGJava 177 | 178 | 179 | Threading issuesJava 180 | 181 | 182 | Visibility issuesJava 183 | 184 | 185 | 186 | 187 | Android 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 209 | 210 | 211 | 212 | 213 | 1.8 214 | 215 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 231 | 232 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RedBook 2 | like red book note detail 3 | >仿小红书,笔记详情 4 | ![RedBook](https://github.com/BelongsH/RedBook/blob/master/redbook.gif) 5 | 6 | 更多介绍: 7 | http://www.jianshu.com/p/38d784d7aac1 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/app-release.apk -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "24.0.0" 6 | defaultConfig { 7 | applicationId "com.demo.redbook" 8 | minSdkVersion 14 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | dexOptions { 21 | maxProcessCount 6 22 | javaMaxHeapSize "3g" 23 | } 24 | } 25 | 26 | def supportLibVersion = '23.2.1' 27 | 28 | dependencies { 29 | compile fileTree(dir: 'libs', include: ['*.jar']) 30 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 31 | exclude group: 'com.android.support', module: 'support-annotations' 32 | }) 33 | 34 | testCompile 'junit:junit:4.12' 35 | 36 | //----------------------------------supportLibray---------------------------------- 37 | compile "com.android.support:design:${supportLibVersion}" 38 | compile "com.android.support:palette-v7:${supportLibVersion}" 39 | compile "com.android.support:gridlayout-v7:${supportLibVersion}" 40 | 41 | compile 'com.squareup.okhttp3:okhttp:3.4.1' 42 | compile "com.squareup.retrofit2:converter-gson:2.1.0" 43 | compile 'com.jakewharton:butterknife:7.0.1' 44 | compile 'com.hannesdorfmann:adapterdelegates3:3.0.0' 45 | compile 'com.squareup.picasso:picasso:2.5.2' 46 | compile 'com.nianxin:utils:1.0.0' 47 | compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2' 48 | compile 'com.github.bumptech.glide:glide:3.7.0' 49 | compile 'jp.wasabeef:glide-transformations:2.0.1' 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /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 /Users/liuhuiliang/Library/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/androidTest/java/com/demo/redbook/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.demo.redbook; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.demo.redbook", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/adapter/note/CommentDelegate.java: -------------------------------------------------------------------------------- 1 | package com.demo.adapter.note; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.support.v7.widget.StaggeredGridLayoutManager; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import com.bumptech.glide.Glide; 13 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 14 | import com.demo.model.CommentModel; 15 | import com.demo.model.HomeModel; 16 | import com.demo.redbook.R; 17 | import com.hannesdorfmann.adapterdelegates3.AdapterDelegate; 18 | 19 | import java.util.List; 20 | 21 | import butterknife.Bind; 22 | import butterknife.ButterKnife; 23 | import jp.wasabeef.glide.transformations.CropCircleTransformation; 24 | 25 | /** 26 | * Created by liuhuiliang on 16/10/21. 27 | */ 28 | 29 | public class CommentDelegate extends AdapterDelegate> { 30 | @Override 31 | protected boolean isForViewType(@NonNull List items, int position) { 32 | return items.get(position) instanceof CommentModel; 33 | } 34 | 35 | @NonNull 36 | @Override 37 | protected RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) { 38 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_comment, parent, false); 39 | StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 40 | layoutParams.setFullSpan(true); 41 | view.setLayoutParams(layoutParams); 42 | return new ViewHolder(view); 43 | } 44 | 45 | @Override 46 | protected void onBindViewHolder(@NonNull List items, int position, @NonNull RecyclerView.ViewHolder holder, @NonNull List payloads) { 47 | CommentModel model = (CommentModel) items.get(position); 48 | ViewHolder commentHolder = (ViewHolder) holder; 49 | commentHolder.tvCommentContent.setText(model.content); 50 | commentHolder.tvCommentTime.setText(model.time); 51 | commentHolder.tvUserName.setText(model.user.nickname); 52 | Glide.with(commentHolder.itemView.getContext()).load(model.user.images).diskCacheStrategy(DiskCacheStrategy.ALL).bitmapTransform(new CropCircleTransformation(commentHolder.itemView.getContext())).placeholder(R.drawable.ic_default_head).into(commentHolder.ivUserHead); 53 | 54 | } 55 | 56 | 57 | class ViewHolder extends RecyclerView.ViewHolder { 58 | 59 | @Bind(R.id.tvCommentContent) 60 | TextView tvCommentContent; 61 | 62 | @Bind(R.id.tvCommentTime) 63 | TextView tvCommentTime; 64 | 65 | @Bind(R.id.tvUserName) 66 | TextView tvUserName; 67 | 68 | @Bind(R.id.ivUserHead) 69 | ImageView ivUserHead; 70 | 71 | public ViewHolder(View itemView) { 72 | super(itemView); 73 | ButterKnife.bind(this, itemView); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/adapter/note/ContentDelegate.java: -------------------------------------------------------------------------------- 1 | package com.demo.adapter.note; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.support.v7.widget.StaggeredGridLayoutManager; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 15 | import com.demo.model.HomeModel; 16 | import com.demo.model.NoteModel; 17 | import com.demo.model.PictureModel; 18 | import com.demo.redbook.R; 19 | import com.demo.utils.PictureSize; 20 | import com.hannesdorfmann.adapterdelegates3.AdapterDelegate; 21 | 22 | import java.util.List; 23 | 24 | import butterknife.Bind; 25 | import butterknife.ButterKnife; 26 | import common.utils.ScreenUtils; 27 | import jp.wasabeef.glide.transformations.CropCircleTransformation; 28 | 29 | /** 30 | * Created by liuhuiliang on 16/10/14. 31 | */ 32 | 33 | public class ContentDelegate extends AdapterDelegate> { 34 | 35 | 36 | @Override 37 | protected boolean isForViewType(@NonNull List items, int position) { 38 | return items.get(position) instanceof NoteModel; 39 | } 40 | 41 | @NonNull 42 | @Override 43 | protected RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) { 44 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_notes, parent, false); 45 | return new ViewHolder(view); 46 | } 47 | 48 | @Override 49 | protected void onBindViewHolder(@NonNull List items, int position, @NonNull RecyclerView.ViewHolder holder, @NonNull List payloads) { 50 | ViewHolder viewHolder = (ViewHolder) holder; 51 | NoteModel itemModel = (NoteModel) items.get(position); 52 | PictureModel model = itemModel.pictures.get(0); 53 | LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewHolder.ivContentImage.getLayoutParams(); 54 | float halfWidth = (ScreenUtils.getScreenWidth(holder.itemView.getContext()) - 60) / 2; 55 | layoutParams.width = (int) halfWidth; 56 | PictureSize pictureSize = PictureSize.caculatePictureSize(model.height, model.width, (int) halfWidth); 57 | layoutParams.height = pictureSize.getScaleHeight(); 58 | viewHolder.ivContentImage.setLayoutParams(layoutParams); 59 | viewHolder.tvNoteDes.setText(itemModel.desc); 60 | viewHolder.tvNoteTitle.setText(itemModel.title); 61 | viewHolder.tvUserName.setText(itemModel.user.nickname); 62 | viewHolder.tvNoteTitle.setText(itemModel.title); 63 | StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams(); 64 | params.setMargins(15, 15, 15, 15); 65 | holder.itemView.setLayoutParams(params); 66 | Glide.with(holder.itemView.getContext()).load(model.url).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(viewHolder.ivContentImage); 67 | Glide.with(viewHolder.ivContentImage.getContext()).load(itemModel.user.images).override(pictureSize.getScaleWidth(), pictureSize.getScaleHeight()).diskCacheStrategy(DiskCacheStrategy.ALL).bitmapTransform(new CropCircleTransformation(viewHolder.ivUserHead.getContext())).placeholder(R.drawable.ic_default_head).into(viewHolder.ivUserHead); 68 | } 69 | 70 | 71 | class ViewHolder extends RecyclerView.ViewHolder { 72 | 73 | @Bind(R.id.ivContentImage) 74 | ImageView ivContentImage; 75 | 76 | @Bind(R.id.ivUserHead) 77 | ImageView ivUserHead; 78 | 79 | @Bind(R.id.tvNoteTitle) 80 | TextView tvNoteTitle; 81 | 82 | @Bind(R.id.tvUserName) 83 | TextView tvUserName; 84 | 85 | @Bind(R.id.tvNoteDes) 86 | TextView tvNoteDes; 87 | 88 | public ViewHolder(View itemView) { 89 | super(itemView); 90 | ButterKnife.bind(this, itemView); 91 | } 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/adapter/note/HeadDelegate.java: -------------------------------------------------------------------------------- 1 | package com.demo.adapter.note; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.v4.util.SimpleArrayMap; 5 | import android.support.v4.view.PagerAdapter; 6 | import android.support.v4.view.ViewPager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.support.v7.widget.StaggeredGridLayoutManager; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.ImageView; 13 | import android.widget.LinearLayout; 14 | import android.widget.TextView; 15 | 16 | import com.bumptech.glide.Glide; 17 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 18 | import com.demo.model.HomeModel; 19 | import com.demo.model.NoteModel; 20 | import com.demo.model.PictureModel; 21 | import com.demo.redbook.R; 22 | import com.demo.utils.PictureSize; 23 | import com.hannesdorfmann.adapterdelegates3.AdapterDelegate; 24 | 25 | import java.util.List; 26 | 27 | import butterknife.Bind; 28 | import butterknife.ButterKnife; 29 | import common.utils.ScreenUtils; 30 | import jp.wasabeef.glide.transformations.CropCircleTransformation; 31 | 32 | /** 33 | * Created by liuhuiliang on 16/10/14. 34 | */ 35 | 36 | public class HeadDelegate extends AdapterDelegate> { 37 | 38 | private SimpleArrayMap mPictureSizes = new SimpleArrayMap<>(); 39 | private NoteModel mNoteModel; 40 | float screenWidth; 41 | 42 | @Override 43 | protected boolean isForViewType(@NonNull List items, int position) { 44 | HomeModel model = items.get(0); 45 | if (model instanceof NoteModel) { 46 | mNoteModel = (NoteModel) model; 47 | } 48 | return position == 0; 49 | } 50 | 51 | @NonNull 52 | @Override 53 | protected RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) { 54 | HeadViewHolder headViewHolder = new HeadViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_head, parent, false)); 55 | StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 56 | layoutParams.setFullSpan(true); 57 | headViewHolder.itemView.setLayoutParams(layoutParams); 58 | screenWidth = (ScreenUtils.getScreenWidth(parent.getContext()) + 0f); 59 | return headViewHolder; 60 | } 61 | 62 | @Override 63 | protected void onBindViewHolder(@NonNull final List items, int position, @NonNull final RecyclerView.ViewHolder holder, @NonNull List payloads) { 64 | final HeadViewHolder holder1 = (HeadViewHolder) holder; 65 | holder1.vpHeadDelegate.setOffscreenPageLimit(mNoteModel.pictures.size()); 66 | holder1.vpHeadDelegate.setAdapter(new PagerAdapter() { 67 | @Override 68 | public int getCount() { 69 | return mNoteModel.pictures.size(); 70 | } 71 | 72 | @Override 73 | public boolean isViewFromObject(View view, Object object) { 74 | return view == object; 75 | } 76 | 77 | @Override 78 | public Object instantiateItem(ViewGroup container, int position) { 79 | ImageView imageView = new ImageView(holder1.vpHeadDelegate.getContext()); 80 | imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 81 | imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewPager.LayoutParams.MATCH_PARENT, ViewPager.LayoutParams.MATCH_PARENT)); 82 | container.addView(imageView); 83 | PictureSize pictureSize = mPictureSizes.get(String.valueOf(position)); 84 | if (pictureSize == null) { 85 | LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) container.getLayoutParams(); 86 | PictureModel pictureModel = mNoteModel.pictures.get(position); 87 | pictureSize = PictureSize.caculatePictureSize(pictureModel.height, pictureModel.width, (int) screenWidth); 88 | mPictureSizes.put(String.valueOf(position), pictureSize); 89 | params.height = pictureSize.getScaleHeight(); 90 | params.width = pictureSize.getScaleWidth(); 91 | container.setLayoutParams(params); 92 | imageView.requestLayout(); 93 | } 94 | Glide.with(holder1.vpHeadDelegate.getContext()).load(mNoteModel.pictures.get(position).url).override(pictureSize.getScaleWidth(), pictureSize.getScaleHeight()).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(imageView); 95 | return imageView; 96 | } 97 | 98 | @Override 99 | public void destroyItem(ViewGroup container, int position, Object object) { 100 | container.removeAllViews(); 101 | } 102 | }); 103 | holder1.vpHeadDelegate.setPageTransformer(true, new ViewPager.PageTransformer() { 104 | @Override 105 | public void transformPage(View page, float position) { 106 | if (position > 0 && position <= 1) { 107 | int badgePosition = (int) (page.getX() / screenWidth) - 1; 108 | PictureSize offsetModel = mPictureSizes.get(String.valueOf(badgePosition + 1)); 109 | if (offsetModel == null) return; 110 | PictureSize nowModel = mPictureSizes.get(String.valueOf(badgePosition)); 111 | float disHeight = (offsetModel.getScaleHeight() - nowModel.getScaleHeight()) * (1 - position); 112 | LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder1.vpHeadDelegate.getLayoutParams(); 113 | params.width = nowModel.getScaleWidth(); 114 | params.height = (int) (nowModel.getScaleHeight() + disHeight); 115 | holder1.vpHeadDelegate.setLayoutParams(params); 116 | holder1.vpHeadDelegate.requestLayout(); 117 | } 118 | } 119 | }); 120 | holder1.tvDes.setText(mNoteModel.desc); 121 | holder1.tvUserName.setText(mNoteModel.user.nickname); 122 | Glide.with(holder1.vpHeadDelegate.getContext()).load(mNoteModel.user.images).diskCacheStrategy(DiskCacheStrategy.ALL).bitmapTransform(new CropCircleTransformation(holder1.vpHeadDelegate.getContext())).placeholder(R.drawable.ic_default_head).into(holder1.ivHeadPicture); 123 | } 124 | 125 | 126 | class HeadViewHolder extends RecyclerView.ViewHolder { 127 | 128 | @Bind(R.id.vpHeadDelegate) 129 | ViewPager vpHeadDelegate; 130 | 131 | @Bind(R.id.tvDes) 132 | TextView tvDes; 133 | 134 | @Bind(R.id.tvUserName) 135 | TextView tvUserName; 136 | 137 | 138 | @Bind(R.id.ivHeadPicture) 139 | ImageView ivHeadPicture; 140 | 141 | public HeadViewHolder(View itemView) { 142 | super(itemView); 143 | ButterKnife.bind(this, itemView); 144 | } 145 | } 146 | 147 | 148 | } -------------------------------------------------------------------------------- /app/src/main/java/com/demo/adapter/note/HomeAdapter.java: -------------------------------------------------------------------------------- 1 | package com.demo.adapter.note; 2 | 3 | import com.demo.model.HomeModel; 4 | import com.hannesdorfmann.adapterdelegates3.AbsDelegationAdapter; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by liuhuiliang on 16/10/14. 10 | */ 11 | 12 | public class HomeAdapter extends AbsDelegationAdapter> { 13 | 14 | private List mDatas; 15 | 16 | public HomeAdapter(List datas) { 17 | super(); 18 | setItems(datas); 19 | this.mDatas = datas; 20 | this.delegatesManager.addDelegate(new HeadDelegate()); 21 | this.delegatesManager.addDelegate(new ContentDelegate()); 22 | this.delegatesManager.addDelegate(new CommentDelegate()); 23 | } 24 | 25 | @Override 26 | public int getItemCount() { 27 | return mDatas.size(); 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/app/App.java: -------------------------------------------------------------------------------- 1 | package com.demo.app; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.os.Environment; 6 | 7 | import com.demo.redbook.BuildConfig; 8 | import com.jakewharton.picasso.OkHttp3Downloader; 9 | import com.squareup.picasso.LruCache; 10 | import com.squareup.picasso.Picasso; 11 | 12 | import java.io.File; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | import okhttp3.Cache; 16 | import okhttp3.OkHttpClient; 17 | 18 | /** 19 | * Created by liuhuiliang on 16/10/14. 20 | */ 21 | 22 | public class App extends Application { 23 | 24 | @Override 25 | protected void attachBaseContext(Context base) { 26 | super.attachBaseContext(base); 27 | } 28 | 29 | @Override 30 | public void onCreate() { 31 | super.onCreate(); 32 | int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 4); 33 | Cache cache = new Cache(new File(Environment.getExternalStorageDirectory().getPath() + "/RedBook"), 100 * 1024 * 1024); 34 | OkHttpClient okHttpClient = new OkHttpClient.Builder() 35 | .retryOnConnectionFailure(true) 36 | .connectTimeout(15, TimeUnit.SECONDS) 37 | .cache(cache) 38 | .build(); 39 | 40 | Picasso picasso = new Picasso.Builder(getApplicationContext()) 41 | .memoryCache(new LruCache(maxMemory)) 42 | .downloader(new OkHttp3Downloader(okHttpClient)) 43 | .build(); 44 | picasso.setIndicatorsEnabled(BuildConfig.DEBUG); // For debugging 45 | Picasso.setSingletonInstance(picasso); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/data/RedBookData.java: -------------------------------------------------------------------------------- 1 | package com.demo.data; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | 6 | import com.demo.model.CommentModel; 7 | import com.demo.model.NoteModel; 8 | import com.google.gson.Gson; 9 | 10 | import org.json.JSONArray; 11 | import org.json.JSONObject; 12 | 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.concurrent.ExecutorService; 17 | import java.util.concurrent.Executors; 18 | 19 | import okhttp3.Call; 20 | import okhttp3.OkHttpClient; 21 | import okhttp3.Request; 22 | import okhttp3.Response; 23 | 24 | /** 25 | * Created by liuhuiliang on 16/10/14. 26 | */ 27 | 28 | public class RedBookData { 29 | 30 | private static final String LIST_URL = "http://www.xiaohongshu.com/api/sns/v2/note/580d4fc936b2a84102ba4716/related?page=1&tag_oid=&platform=Android&deviceId=604fae2e-8a44-3b43-8297-ec5b00f7bf66&versionName=4.10.100&channel=Xiaomi&sid=session.1160904632837462555&lang=zh-CN&t=1477460298&sign=8d6d648f17a78e3c7d099957d7e19900"; 31 | private static final String COMMENT_URL = "http://www.xiaohongshu.com/api/sns/v5/note/580d4fc936b2a84102ba4716?platform=Android&deviceId=604fae2e-8a44-3b43-8297-ec5b00f7bf66&versionName=4.10.100&channel=Xiaomi&sid=session.1160904632837462555&lang=zh-CN&t=1477460298&sign=402ee8dd97ed4a52e8a2721e3cdb3933"; 32 | 33 | public static void getRedBookDataAsy(final RedBookCallback callback) { 34 | if (callback == null) return; 35 | final List models = new ArrayList<>(); 36 | final List commentModels = new ArrayList<>(); 37 | ExecutorService service = Executors.newSingleThreadExecutor(); 38 | service.execute(new Runnable() { 39 | @Override 40 | public void run() { 41 | OkHttpClient client = new OkHttpClient(); 42 | try { 43 | Response listResponse = client.newCall(new Request.Builder().url(LIST_URL).build()).execute(); 44 | Response commentResponse = client.newCall(new Request.Builder().url(COMMENT_URL).build()).execute(); 45 | JSONObject listJson = new JSONObject(listResponse.body().string()); 46 | JSONObject commentJson = new JSONObject(commentResponse.body().string()); 47 | JSONArray jsonArray = listJson.getJSONArray("data"); 48 | //列表 49 | for (int j = 0; j < jsonArray.length(); j++) { 50 | NoteModel model = new Gson().fromJson(jsonArray.get(j).toString(), NoteModel.class); 51 | models.add(model); 52 | } 53 | //评论 54 | JSONArray commentJsonJSONArray = commentJson.getJSONObject("data").getJSONArray("comments_list"); 55 | for (int i = 0; i < commentJsonJSONArray.length(); i++) { 56 | CommentModel model = new Gson().fromJson(commentJsonJSONArray.get(i).toString(), CommentModel.class); 57 | commentModels.add(model); 58 | } 59 | new Handler(Looper.getMainLooper()).post(new Runnable() { 60 | @Override 61 | public void run() { 62 | callback.onResponse(models, commentModels); 63 | } 64 | }); 65 | 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | }); 71 | 72 | } 73 | 74 | 75 | public interface RedBookCallback { 76 | 77 | void onFailure(Call call, IOException e); 78 | 79 | void onResponse(List datas, List models); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/model/CommentModel.java: -------------------------------------------------------------------------------- 1 | package com.demo.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by liuhuiliang on 16/10/21. 8 | */ 9 | 10 | public class CommentModel implements HomeModel, Parcelable { 11 | 12 | 13 | public String content; 14 | public int like_count; 15 | public String time; 16 | public UserModel user; 17 | 18 | 19 | @Override 20 | public int describeContents() { 21 | return 0; 22 | } 23 | 24 | @Override 25 | public void writeToParcel(Parcel dest, int flags) { 26 | dest.writeString(this.content); 27 | dest.writeInt(this.like_count); 28 | dest.writeString(this.time); 29 | dest.writeParcelable(this.user, flags); 30 | } 31 | 32 | public CommentModel() { 33 | } 34 | 35 | protected CommentModel(Parcel in) { 36 | this.content = in.readString(); 37 | this.like_count = in.readInt(); 38 | this.time = in.readString(); 39 | this.user = in.readParcelable(UserModel.class.getClassLoader()); 40 | } 41 | 42 | public static final Creator CREATOR = new Creator() { 43 | @Override 44 | public CommentModel createFromParcel(Parcel source) { 45 | return new CommentModel(source); 46 | } 47 | 48 | @Override 49 | public CommentModel[] newArray(int size) { 50 | return new CommentModel[size]; 51 | } 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/model/HomeModel.java: -------------------------------------------------------------------------------- 1 | package com.demo.model; 2 | 3 | /** 4 | * Created by liuhuiliang on 16/10/21. 5 | */ 6 | 7 | public interface HomeModel { 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/model/NoteModel.java: -------------------------------------------------------------------------------- 1 | package com.demo.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by liuhuiliang on 16/10/14. 12 | */ 13 | 14 | public class NoteModel implements Parcelable, HomeModel { 15 | 16 | public String title; 17 | 18 | public String desc; 19 | 20 | @SerializedName("images_list") 21 | public List pictures; 22 | 23 | public UserModel user; 24 | 25 | public int likes; 26 | 27 | 28 | @Override 29 | public int describeContents() { 30 | return 0; 31 | } 32 | 33 | @Override 34 | public void writeToParcel(Parcel dest, int flags) { 35 | dest.writeString(this.title); 36 | dest.writeString(this.desc); 37 | dest.writeTypedList(pictures); 38 | } 39 | 40 | public NoteModel() { 41 | } 42 | 43 | protected NoteModel(Parcel in) { 44 | this.title = in.readString(); 45 | this.desc = in.readString(); 46 | this.pictures = in.createTypedArrayList(PictureModel.CREATOR); 47 | } 48 | 49 | public static final Creator CREATOR = new Creator() { 50 | @Override 51 | public NoteModel createFromParcel(Parcel source) { 52 | return new NoteModel(source); 53 | } 54 | 55 | @Override 56 | public NoteModel[] newArray(int size) { 57 | return new NoteModel[size]; 58 | } 59 | }; 60 | 61 | @Override 62 | public String toString() { 63 | return "NoteModel{" + 64 | "title='" + title + '\'' + 65 | ", desc='" + desc + '\'' + 66 | ", pictures=" + pictures + 67 | '}'; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/model/PictureModel.java: -------------------------------------------------------------------------------- 1 | package com.demo.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by liuhuiliang on 16/10/14. 8 | */ 9 | 10 | public class PictureModel implements Parcelable { 11 | 12 | 13 | public String url; 14 | public String original; 15 | public int height; 16 | public int width; 17 | 18 | 19 | @Override 20 | public int describeContents() { 21 | return 0; 22 | } 23 | 24 | @Override 25 | public void writeToParcel(Parcel dest, int flags) { 26 | dest.writeString(this.url); 27 | dest.writeString(this.original); 28 | dest.writeInt(this.height); 29 | dest.writeInt(this.width); 30 | } 31 | 32 | public PictureModel() { 33 | } 34 | 35 | protected PictureModel(Parcel in) { 36 | this.url = in.readString(); 37 | this.original = in.readString(); 38 | this.height = in.readInt(); 39 | this.width = in.readInt(); 40 | } 41 | 42 | public static final Creator CREATOR = new Creator() { 43 | @Override 44 | public PictureModel createFromParcel(Parcel source) { 45 | return new PictureModel(source); 46 | } 47 | 48 | @Override 49 | public PictureModel[] newArray(int size) { 50 | return new PictureModel[size]; 51 | } 52 | }; 53 | 54 | @Override 55 | public String toString() { 56 | return "PictureModel{" + 57 | "url='" + url + '\'' + 58 | ", original='" + original + '\'' + 59 | ", height=" + height + 60 | ", width=" + width + 61 | '}'; 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/model/SizeModel.java: -------------------------------------------------------------------------------- 1 | package com.demo.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by liuhuiliang on 16/10/20. 8 | */ 9 | 10 | public class SizeModel implements Parcelable { 11 | 12 | private float scaleX; 13 | 14 | public SizeModel caculateScale(PictureModel nowModel, PictureModel offsetModel, float screenWidth) { 15 | if (offsetModel == null) return new SizeModel(); 16 | float nowZoom = (screenWidth + 0f) / nowModel.width; 17 | float nextZoom = (screenWidth + 0f) / offsetModel.width; 18 | float nowZoomHeight = (nowModel.height * nowZoom); 19 | float nextZoomHeight = (offsetModel.height * nextZoom); 20 | this.scaleX = nowZoomHeight / nextZoomHeight; 21 | return this; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "SizeModel{" + 27 | "scaleX=" + scaleX + 28 | '}'; 29 | } 30 | 31 | 32 | @Override 33 | public int describeContents() { 34 | return 0; 35 | } 36 | 37 | @Override 38 | public void writeToParcel(Parcel dest, int flags) { 39 | dest.writeFloat(this.scaleX); 40 | } 41 | 42 | public SizeModel() { 43 | } 44 | 45 | protected SizeModel(Parcel in) { 46 | this.scaleX = in.readFloat(); 47 | } 48 | 49 | public static final Creator CREATOR = new Creator() { 50 | @Override 51 | public SizeModel createFromParcel(Parcel source) { 52 | return new SizeModel(source); 53 | } 54 | 55 | @Override 56 | public SizeModel[] newArray(int size) { 57 | return new SizeModel[size]; 58 | } 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/model/UserModel.java: -------------------------------------------------------------------------------- 1 | package com.demo.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by liuhuiliang on 16/10/19. 8 | */ 9 | 10 | public class UserModel implements Parcelable { 11 | 12 | public String userid; 13 | public String images; 14 | public String nickname; 15 | 16 | 17 | @Override 18 | public int describeContents() { 19 | return 0; 20 | } 21 | 22 | @Override 23 | public void writeToParcel(Parcel dest, int flags) { 24 | dest.writeString(this.userid); 25 | dest.writeString(this.images); 26 | dest.writeString(this.nickname); 27 | } 28 | 29 | public UserModel() { 30 | } 31 | 32 | protected UserModel(Parcel in) { 33 | this.userid = in.readString(); 34 | this.images = in.readString(); 35 | this.nickname = in.readString(); 36 | } 37 | 38 | public static final Creator CREATOR = new Creator() { 39 | @Override 40 | public UserModel createFromParcel(Parcel source) { 41 | return new UserModel(source); 42 | } 43 | 44 | @Override 45 | public UserModel[] newArray(int size) { 46 | return new UserModel[size]; 47 | } 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/redbook/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.demo.redbook; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | import android.os.Build; 6 | import android.os.Bundle; 7 | import android.support.annotation.RequiresApi; 8 | import android.support.v4.content.ContextCompat; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.support.v7.widget.StaggeredGridLayoutManager; 12 | import android.view.View; 13 | 14 | import com.demo.adapter.note.HomeAdapter; 15 | import com.demo.data.RedBookData; 16 | import com.demo.model.CommentModel; 17 | import com.demo.model.HomeModel; 18 | import com.demo.model.NoteModel; 19 | import com.demo.utils.StatusBarUtils; 20 | 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import butterknife.Bind; 26 | import butterknife.ButterKnife; 27 | import okhttp3.Call; 28 | 29 | public class MainActivity extends AppCompatActivity implements RedBookData.RedBookCallback { 30 | 31 | 32 | @Bind(R.id.rvMain) 33 | RecyclerView rvMain; 34 | 35 | List mPictureModels = new ArrayList<>(); 36 | HomeAdapter mHomeAdapter; 37 | 38 | 39 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 40 | @Override 41 | protected void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.activity_main); 44 | ButterKnife.bind(this); 45 | RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); 46 | RecyclerView.ItemDecoration itemDecoration=new RecyclerView.ItemDecoration() { 47 | @Override 48 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { 49 | super.onDraw(c, parent, state); 50 | } 51 | 52 | @Override 53 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 54 | super.getItemOffsets(outRect, view, parent, state); 55 | } 56 | }; 57 | rvMain.setLayoutManager(layoutManager); 58 | mHomeAdapter = new HomeAdapter(mPictureModels); 59 | rvMain.setAdapter(mHomeAdapter); 60 | RedBookData.getRedBookDataAsy(this); 61 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 62 | getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimary)); 63 | } 64 | StatusBarUtils.MIUISetStatusBarLightMode(getWindow(), true); 65 | } 66 | 67 | 68 | @Override 69 | public void onFailure(Call call, IOException e) { 70 | 71 | } 72 | 73 | @Override 74 | public void onResponse(List datas, List models) { 75 | mPictureModels.clear(); 76 | mPictureModels.add(datas.get(0)); 77 | mPictureModels.addAll(models); 78 | mPictureModels.addAll(datas); 79 | mHomeAdapter.notifyDataSetChanged(); 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/demo/utils/PictureSize.java: -------------------------------------------------------------------------------- 1 | package com.demo.utils; 2 | 3 | /** 4 | * Created by liuhuiliang on 16/10/21. 5 | */ 6 | 7 | public class PictureSize { 8 | private int originalHeight; 9 | private int originalWidth; 10 | private float scale; 11 | private int scaleHeight; 12 | private int scaleWidth; 13 | 14 | 15 | public static PictureSize caculatePictureSize(int originalHeight, int originalWidth, int screenWidth) { 16 | PictureSize pictureSize = new PictureSize(); 17 | pictureSize.originalHeight = originalHeight; 18 | pictureSize.originalWidth = originalWidth; 19 | pictureSize.scale = (screenWidth + 0f) / originalWidth; 20 | pictureSize.scaleHeight = (int) (originalHeight * pictureSize.scale); 21 | pictureSize.scaleWidth = screenWidth; 22 | return pictureSize; 23 | } 24 | 25 | 26 | public int getOriginalHeight() { 27 | return originalHeight; 28 | } 29 | 30 | public void setOriginalHeight(int originalHeight) { 31 | this.originalHeight = originalHeight; 32 | } 33 | 34 | public int getOriginalWidth() { 35 | return originalWidth; 36 | } 37 | 38 | public void setOriginalWidth(int originalWidth) { 39 | this.originalWidth = originalWidth; 40 | } 41 | 42 | public float getScale() { 43 | return scale; 44 | } 45 | 46 | public void setScale(float scale) { 47 | this.scale = scale; 48 | } 49 | 50 | public int getScaleHeight() { 51 | return scaleHeight; 52 | } 53 | 54 | public void setScaleHeight(int scaleHeight) { 55 | this.scaleHeight = scaleHeight; 56 | } 57 | 58 | public int getScaleWidth() { 59 | return scaleWidth; 60 | } 61 | 62 | public void setScaleWidth(int scaleWidth) { 63 | this.scaleWidth = scaleWidth; 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/demo/utils/StatusBarUtils.java: -------------------------------------------------------------------------------- 1 | package com.demo.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.Activity; 5 | import android.graphics.Color; 6 | import android.os.Build; 7 | import android.view.View; 8 | import android.view.Window; 9 | import android.view.WindowManager; 10 | 11 | import java.lang.reflect.Field; 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * Created by liuhuiliang on 16/10/21. 16 | */ 17 | public class StatusBarUtils { 18 | 19 | /** 20 | * 修改状态栏为全透明 21 | * 22 | * @param activity 23 | */ 24 | @TargetApi(19) 25 | public static void transparencyBar(Activity activity) { 26 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 27 | Window window = activity.getWindow(); 28 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS 29 | | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 30 | window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 31 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 32 | | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 33 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 34 | window.setStatusBarColor(Color.TRANSPARENT); 35 | window.setNavigationBarColor(Color.TRANSPARENT); 36 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 37 | Window window = activity.getWindow(); 38 | window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, 39 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 40 | } 41 | } 42 | 43 | 44 | /** 45 | * 设置状态栏黑色字体图标, 46 | * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android 47 | * 48 | * @param activity 49 | * @return 1:MIUUI 2:Flyme 3:android6.0 50 | */ 51 | public static int StatusBarLightMode(Activity activity) { 52 | int result = 0; 53 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 54 | if (MIUISetStatusBarLightMode(activity.getWindow(), true)) { 55 | result = 1; 56 | } else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) { 57 | result = 2; 58 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 59 | activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 60 | result = 3; 61 | } 62 | } 63 | return result; 64 | } 65 | 66 | /** 67 | * 已知系统类型时,设置状态栏黑色字体图标。 68 | * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android 69 | * 70 | * @param activity 71 | * @param type 1:MIUUI 2:Flyme 3:android6.0 72 | */ 73 | public static void StatusBarLightMode(Activity activity, int type) { 74 | if (type == 1) { 75 | MIUISetStatusBarLightMode(activity.getWindow(), true); 76 | } else if (type == 2) { 77 | FlymeSetStatusBarLightMode(activity.getWindow(), true); 78 | } else if (type == 3) { 79 | activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 80 | } 81 | 82 | } 83 | 84 | /** 85 | * 清除MIUI或flyme或6.0以上版本状态栏黑色字体 86 | */ 87 | public static void StatusBarDarkMode(Activity activity, int type) { 88 | if (type == 1) { 89 | MIUISetStatusBarLightMode(activity.getWindow(), false); 90 | } else if (type == 2) { 91 | FlymeSetStatusBarLightMode(activity.getWindow(), false); 92 | } else if (type == 3) { 93 | activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 94 | } 95 | 96 | } 97 | 98 | 99 | /** 100 | * 设置状态栏图标为深色和魅族特定的文字风格 101 | * 可以用来判断是否为Flyme用户 102 | * 103 | * @param window 需要设置的窗口 104 | * @param dark 是否把状态栏字体及图标颜色设置为深色 105 | * @return boolean 成功执行返回true 106 | */ 107 | public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) { 108 | boolean result = false; 109 | if (window != null) { 110 | try { 111 | WindowManager.LayoutParams lp = window.getAttributes(); 112 | Field darkFlag = WindowManager.LayoutParams.class 113 | .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON"); 114 | Field meizuFlags = WindowManager.LayoutParams.class 115 | .getDeclaredField("meizuFlags"); 116 | darkFlag.setAccessible(true); 117 | meizuFlags.setAccessible(true); 118 | int bit = darkFlag.getInt(null); 119 | int value = meizuFlags.getInt(lp); 120 | if (dark) { 121 | value |= bit; 122 | } else { 123 | value &= ~bit; 124 | } 125 | meizuFlags.setInt(lp, value); 126 | window.setAttributes(lp); 127 | result = true; 128 | } catch (Exception e) { 129 | 130 | } 131 | } 132 | return result; 133 | } 134 | 135 | /** 136 | * 设置状态栏字体图标为深色,需要MIUIV6以上 137 | * 138 | * @param window 需要设置的窗口 139 | * @param dark 是否把状态栏字体及图标颜色设置为深色 140 | * @return boolean 成功执行返回true 141 | */ 142 | public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) { 143 | boolean result = false; 144 | if (window != null) { 145 | Class clazz = window.getClass(); 146 | try { 147 | int darkModeFlag = 0; 148 | Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); 149 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); 150 | darkModeFlag = field.getInt(layoutParams); 151 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); 152 | if (dark) { 153 | extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体 154 | } else { 155 | extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体 156 | } 157 | result = true; 158 | } catch (Exception e) { 159 | 160 | } 161 | } 162 | return result; 163 | } 164 | 165 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_note_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-hdpi/ic_note_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/common_head_btn_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-xxhdpi/common_head_btn_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_default_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-xxhdpi/ic_default_head.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_like_count_def.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-xxhdpi/ic_like_count_def.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/note_icon_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-xxhdpi/note_icon_comment.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/note_icon_fav_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-xxhdpi/note_icon_fav_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/note_icon_like_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/drawable-xxhdpi/note_icon_like_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/sp_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 20 | 21 | 24 | 25 | 32 | 33 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 57 | 58 | 65 | 66 | 71 | 72 | 82 | 83 | 84 | 85 | 90 | 91 | 100 | 101 | 102 | 103 | 109 | 110 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_note_comment.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 15 | 16 | 23 | 24 | 25 | 31 | 32 | 33 | 42 | 43 | 54 | 55 | 56 | 57 | 58 | 70 | 71 | 72 | 77 | 78 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_note_head.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 16 | 17 | 25 | 26 | 37 | 38 | 39 | 54 | 55 | 56 | 57 | 58 | 63 | 64 | 65 | 70 | 71 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_note_notes.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 16 | 17 | 22 | 23 | 28 | 29 | 30 | 34 | 35 | 45 | 46 | 56 | 57 | 58 | 59 | 64 | 65 | 72 | 73 | 83 | 84 | 85 | 86 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FEFEFE 4 | #FEFEFE 5 | #FEFEFE 6 | #cc0000 7 | #000000 8 | #4d4d4d 9 | #EFEFEF 10 | 11 | 12 | 13 | 14 | #fffafafa 15 | 16 | #FCFCFC 17 | #999999 18 | #FFFFFF 19 | #DFDFDF 20 | #1fb6ed 21 | #FFFFFF 22 | #F4F4F4 23 | #E7E7E7 24 | #1fb6ed 25 | #484848 26 | #FFFFFF 27 | #A6A6A6 28 | #636363 29 | #ECECEC 30 | #C3C3C3 31 | #F9F9F9 32 | #A7A7A7 33 | #272727 34 | #1A1A1A 35 | #000000 36 | #5A5A5A 37 | #2E2E2E 38 | #2C2C2C 39 | #1fb6ed 40 | #1c9ac8 41 | #f76500 42 | #fb812c 43 | #EFF6FF 44 | #FBFDFF 45 | #7b7b7b 46 | #646464 47 | #000000 48 | 49 | #1fb6ed 50 | #ffffff 51 | #1fb6ed 52 | #646464 53 | #464646 54 | 55 | #1f1f1f 56 | #c2c2c2 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RedBook 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/test/java/com/demo/redbook/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.demo.redbook; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | 20 | 21 | apply plugin: 'checkstyle' 22 | task checkstyle(type: Checkstyle) { 23 | source 'src/main/java' 24 | ignoreFailures false 25 | showViolations true 26 | include '**/*.java' 27 | configFile new File(rootDir, "checkstyle.xml") 28 | // empty classpath 29 | classpath = files() 30 | } 31 | } 32 | 33 | task clean(type: Delete) { 34 | delete rootProject.buildDir 35 | } 36 | -------------------------------------------------------------------------------- /checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | #org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | 16 | org.gradle.jvmargs=-Xmx4096m 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /redbook.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BelongsH/RedBook/30add3536ddc279623b55a1f487c5d9725c622d4/redbook.gif -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------