From 865f2573d7a9b6090309e17997575abea146f790 Mon Sep 17 00:00:00 2001 From: joe Date: Tue, 5 Sep 2017 16:13:42 +0800 Subject: [PATCH] add setting and about view and so on .. --- app/build.gradle | 13 +- app/google-services.json | 42 +++++ app/proguard-rules.pro | 15 +- app/src/main/AndroidManifest.xml | 6 + .../java/com/lovejjfg/readhub/base/App.kt | 1 + .../lovejjfg/readhub/base/RefreshFragment.kt | 2 +- .../readhub/data/{Test.kt => Library.kt} | 40 ++--- .../com/lovejjfg/readhub/utils/JumpUitl.kt | 41 ++++- .../lovejjfg/readhub/view/AboutActivity.kt | 109 +++++++++++++ .../com/lovejjfg/readhub/view/CustomFab.kt | 56 +++++++ .../lovejjfg/readhub/view/CustomLayout.java | 151 ++++++++++++++++++ .../com/lovejjfg/readhub/view/HomeActivity.kt | 49 +++++- .../lovejjfg/readhub/view/SettingsActivity.kt | 136 ++-------------- .../readhub/view/fragment/HotTopicAdapter.kt | 9 +- app/src/main/res/layout/activity_about.xml | 110 +++++++++++++ app/src/main/res/layout/activity_home.xml | 9 +- app/src/main/res/layout/activity_web.xml | 16 +- app/src/main/res/layout/holder_about_info.xml | 68 ++++++++ app/src/main/res/layout/holder_hot_topic.xml | 4 +- .../main/res/layout/holder_normal_topic.xml | 13 +- app/src/main/res/menu/home.xml | 34 ++++ app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/dimens.xml | 10 +- app/src/main/res/values/strings.xml | 14 +- app/src/main/res/values/styles.xml | 45 +++++- app/src/main/res/xml/pref_general.xml | 41 ++--- app/src/main/res/xml/pref_headers.xml | 10 -- build.gradle | 10 +- gradle.properties | 4 +- util.gradle | 69 ++++++++ 30 files changed, 889 insertions(+), 239 deletions(-) create mode 100644 app/google-services.json rename app/src/main/java/com/lovejjfg/readhub/data/{Test.kt => Library.kt} (56%) create mode 100644 app/src/main/java/com/lovejjfg/readhub/view/AboutActivity.kt create mode 100644 app/src/main/java/com/lovejjfg/readhub/view/CustomFab.kt create mode 100644 app/src/main/java/com/lovejjfg/readhub/view/CustomLayout.java create mode 100644 app/src/main/res/layout/activity_about.xml create mode 100644 app/src/main/res/layout/holder_about_info.xml create mode 100644 app/src/main/res/menu/home.xml create mode 100644 util.gradle diff --git a/app/build.gradle b/app/build.gradle index d2f3b4a..1fe7edf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,9 +9,11 @@ android { applicationId "com.lovejjfg.readhub" minSdkVersion MIN_SDK_VERSION targetSdkVersion TARGET_SDK_VERSION - versionCode 1 - versionName "1.0" + versionCode project.gitCommitCount + versionName project.gitTag testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + //只保留对应的国际化 + resConfigs "zh", "en" } buildTypes { release { @@ -19,9 +21,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { - shrinkResources false + shrinkResources true minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -40,6 +42,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.google.firebase:firebase-core:11.2.0' androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) @@ -65,3 +68,5 @@ dependencies { testImplementation 'junit:junit:4.12' } + +apply plugin: 'com.google.gms.google-services' diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..ebb713f --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "689745366156", + "firebase_url": "https://readhub-46dc0.firebaseio.com", + "project_id": "readhub-46dc0", + "storage_bucket": "readhub-46dc0.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:689745366156:android:7c480c335dec1735", + "android_client_info": { + "package_name": "com.lovejjfg.readhub" + } + }, + "oauth_client": [ + { + "client_id": "689745366156-bisjq0200nash35ma70cdk5hol4mhhg9.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCVAQyvtIilb2FsdgqQneeKojWII5L98uI" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6e6bd85..98e2aca 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -24,12 +24,9 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile # okhttp --dontwarn com.squareup.okhttp3.** --keep class com.squareup.okhttp3.** { *;} --keep interface com.squareup.okhttp3.** { *; } +-dontwarn okio.** -dontwarn javax.annotation.Nullable -dontwarn javax.annotation.ParametersAreNonnullByDefault --dontwarn okio.** #retrofit @@ -37,18 +34,20 @@ -dontnote retrofit2.Platform # Platform used when running on Java 8 VMs. Will not be used at runtime. -dontwarn retrofit2.Platform$Java8 --dontwarn retrofit2.OkHttpCall +#-dontwarn retrofit2.OkHttpCall # Retain generic type information for use by reflection by converters and adapters. -keepattributes Signature # Retain declared checked exceptions for use by a Proxy instance. -keepattributes Exceptions + +-dontwarn javax.annotation.** # keep anotation -keepclasseswithmembers class * { @retrofit2.http.* ; } - --dontwarn rx.** +#rx +#-dontwarn rx.** # lambda -dontwarn java.lang.invoke.* @@ -61,5 +60,7 @@ -dontwarn com.lovejjfg.** +-keepattributes EnclosingMethod + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fb13cac..4ed1340 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,10 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/lovejjfg/readhub/base/App.kt b/app/src/main/java/com/lovejjfg/readhub/base/App.kt index efa453c..36e7ec4 100644 --- a/app/src/main/java/com/lovejjfg/readhub/base/App.kt +++ b/app/src/main/java/com/lovejjfg/readhub/base/App.kt @@ -19,6 +19,7 @@ package com.lovejjfg.readhub.base import android.app.Application +import com.google.firebase.analytics.FirebaseAnalytics /** diff --git a/app/src/main/java/com/lovejjfg/readhub/base/RefreshFragment.kt b/app/src/main/java/com/lovejjfg/readhub/base/RefreshFragment.kt index 1a8571c..deac5ff 100644 --- a/app/src/main/java/com/lovejjfg/readhub/base/RefreshFragment.kt +++ b/app/src/main/java/com/lovejjfg/readhub/base/RefreshFragment.kt @@ -145,7 +145,7 @@ abstract class RefreshFragment : Fragment() { }) ?.start() } - if (!isAnimating && dy > 0 && first > 2 && isVisible) { + if (!isAnimating && dy > 0 && isVisible) { navigation?.animate() ?.translationY(navigation?.height!! + 0.5f) ?.setListener(object : AnimatorListenerAdapter() { diff --git a/app/src/main/java/com/lovejjfg/readhub/data/Test.kt b/app/src/main/java/com/lovejjfg/readhub/data/Library.kt similarity index 56% rename from app/src/main/java/com/lovejjfg/readhub/data/Test.kt rename to app/src/main/java/com/lovejjfg/readhub/data/Library.kt index 551b872..cbc2574 100644 --- a/app/src/main/java/com/lovejjfg/readhub/data/Test.kt +++ b/app/src/main/java/com/lovejjfg/readhub/data/Library.kt @@ -20,32 +20,32 @@ package com.lovejjfg.readhub.data import android.os.Parcel import android.os.Parcelable -import com.google.gson.annotations.SerializedName -data class Test( - - @field:SerializedName("name") - val name: String? = "xxxxx", - - @field:SerializedName("age") - val age: Int? = null -) : Parcelable { - companion object { - @JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): Test = Test(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } - } +/** + * Created by Joe on 2017/3/14. + * Email lovejjfg@gmail.com + */ +data class Library(var name: String?, var des: String?, var jumpUrl: String?) : Parcelable { constructor(source: Parcel) : this( source.readString(), - source.readValue(Int::class.java.classLoader) as Int? + source.readString(), + source.readString() ) override fun describeContents() = 0 - override fun writeToParcel(dest: Parcel, flags: Int) { - dest.writeString(name) - dest.writeValue(age) + override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) { + writeString(name) + writeString(des) + writeString(jumpUrl) + } + + companion object { + @JvmField + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(source: Parcel): Library = Library(source) + override fun newArray(size: Int): Array = arrayOfNulls(size) + } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/lovejjfg/readhub/utils/JumpUitl.kt b/app/src/main/java/com/lovejjfg/readhub/utils/JumpUitl.kt index 25ba7aa..932b1b6 100644 --- a/app/src/main/java/com/lovejjfg/readhub/utils/JumpUitl.kt +++ b/app/src/main/java/com/lovejjfg/readhub/utils/JumpUitl.kt @@ -20,10 +20,17 @@ package com.lovejjfg.readhub.utils import android.content.Context import android.content.Intent - +import android.net.Uri +import android.os.Bundle +import android.preference.PreferenceManager +import android.text.TextUtils +import com.google.firebase.analytics.FirebaseAnalytics import com.lovejjfg.readhub.data.Constants +import com.lovejjfg.readhub.view.AboutActivity +import com.lovejjfg.readhub.view.SettingsActivity import com.lovejjfg.readhub.view.WebActivity + /** * ReadHub * Created by Joe at 2017/8/5. @@ -31,9 +38,35 @@ import com.lovejjfg.readhub.view.WebActivity object JumpUitl { - fun jumpWeb(context: Context, url: String) { - val intent = Intent(context, WebActivity::class.java) - intent.putExtra(Constants.URL, url) + fun jumpWeb(context: Context, url: String?) { + if (TextUtils.isEmpty(url)) { + return + } + val bundle = Bundle() + bundle.putString("链接", url) + FirebaseAnalytics.getInstance(context).logEvent("点击", bundle) + val default = PreferenceManager + .getDefaultSharedPreferences(context) + .getBoolean("browser_use", false) + + if (!default) { + val intent = Intent(context, WebActivity::class.java) + intent.putExtra(Constants.URL, url) + context.startActivity(intent) + } else { + val uri = Uri.parse(url) + val intent = Intent(Intent.ACTION_VIEW, uri) + context.startActivity(intent) + } + } + + fun jumpSetting(context: Context) { + val intent = Intent(context, SettingsActivity::class.java) + context.startActivity(intent) + } + + fun jumpAbout(context: Context) { + val intent = Intent(context, AboutActivity::class.java) context.startActivity(intent) } } diff --git a/app/src/main/java/com/lovejjfg/readhub/view/AboutActivity.kt b/app/src/main/java/com/lovejjfg/readhub/view/AboutActivity.kt new file mode 100644 index 0000000..78c919d --- /dev/null +++ b/app/src/main/java/com/lovejjfg/readhub/view/AboutActivity.kt @@ -0,0 +1,109 @@ +/* + * + * Copyright (c) 2017. Joe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.lovejjfg.readhub.view + +import android.databinding.DataBindingUtil +import android.os.Bundle +import android.support.v7.app.AppCompatActivity +import android.support.v7.widget.LinearLayoutManager +import android.view.LayoutInflater +import android.view.ViewGroup +import com.lovejjfg.powerrecycle.PowerAdapter +import com.lovejjfg.powerrecycle.holder.PowerHolder +import com.lovejjfg.readhub.R +import com.lovejjfg.readhub.data.Library +import com.lovejjfg.readhub.databinding.ActivityAboutBinding +import com.lovejjfg.readhub.databinding.HolderAboutInfoBinding +import com.lovejjfg.readhub.utils.JumpUitl +import java.util.* + +/** + * ReadHub + * Created by Joe at 2017/9/5. + */ +class AboutActivity : AppCompatActivity() { + private var aboutAdapter: PowerAdapter? = null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val contentView = DataBindingUtil.setContentView(this, R.layout.activity_about) + contentView?.toolbar?.setNavigationOnClickListener({ finish() }) + aboutAdapter = AboutAdapter() + val recyclerView = contentView?.recyclerView + recyclerView?.layoutManager = LinearLayoutManager(this) + aboutAdapter?.attachRecyclerView(recyclerView!!) + initData() + aboutAdapter?.setOnItemClickListener({ itemView, position, item -> + JumpUitl.jumpWeb(this, item.jumpUrl) + }) + } + + private fun initData() { + val libraries = ArrayList() + libraries.add(Library("Readhub", + "Readhub Android 客户端", + "https://github.com/lovejjfg/Readhub")) + libraries.add(Library("Android support libraries", + "The Android support libraries offer a number of features that are not built into the framework.", + "https://developer.android.com/topic/libraries/support-library")) + libraries.add(Library("OkHttp", + "An HTTP & HTTP/2 client for Android and Java applications.", + "http://square.github.io/okhttp/")) + libraries.add(Library("RxKotlin", + "RxJava bindings for Kotlin.", + "https://github.com/ReactiveX/RxKotlin")) + libraries.add(Library("PowerRecyclerView", + "Easy for RecyclerView to pull refresh and load more.", + "https://github.com/lovejjfg/PowerRecyclerView")) + libraries.add(Library("Retrofit", + "A type-safe HTTP client for Android and Java.", + "http://square.github.io/retrofit/")) + libraries.add(Library("RxAndroid", + "RxJava bindings for Android.", + "https://github.com/ReactiveX/RxAndroid")) + libraries.add(Library("RxJava", + "RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.", + "https://github.com/ReactiveX/RxJava")) + libraries.add(Library("Gson", + "A Java serialization/deserialization library to convert Java Objects into JSON and back", + "https://github.com/google/gson")) + + aboutAdapter?.setList(libraries) + + } + + + class AboutAdapter : PowerAdapter() { + override fun onViewHolderBind(holder: PowerHolder?, position: Int) { + holder?.onBind(list[position]) + } + + override fun onViewHolderCreate(parent: ViewGroup, viewType: Int): PowerHolder? { + val infoBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.holder_about_info, parent, false) + return AboutHolder(infoBinding) + } + + } + + class AboutHolder(itemView: HolderAboutInfoBinding) : PowerHolder(itemView.root) { + private var dataBind: HolderAboutInfoBinding? = itemView + override fun onBind(t: Library?) { + dataBind?.lib = t + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lovejjfg/readhub/view/CustomFab.kt b/app/src/main/java/com/lovejjfg/readhub/view/CustomFab.kt new file mode 100644 index 0000000..0623c6a --- /dev/null +++ b/app/src/main/java/com/lovejjfg/readhub/view/CustomFab.kt @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2017. Joe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.lovejjfg.readhub.view + +import android.content.Context +import android.support.design.widget.FloatingActionButton +import android.support.design.widget.FloatingActionButton.OnVisibilityChangedListener +import android.util.AttributeSet +import com.lovejjfg.readhub.utils.UIUtil + +/** + * ReadHub + * Created by Joe at 2017/9/5. + */ +class CustomFab : FloatingActionButton { + constructor(context: Context) : this(context, null) + + constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, -1) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + + override fun show() { + + } + + override fun show(listener: OnVisibilityChangedListener?) { + super.show(object : OnVisibilityChangedListener() { + override fun onShown(fab: FloatingActionButton?) { + super.onShown(fab) + } + + override fun onHidden(fab: FloatingActionButton?) { + super.onHidden(fab) + } + }) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/lovejjfg/readhub/view/CustomLayout.java b/app/src/main/java/com/lovejjfg/readhub/view/CustomLayout.java new file mode 100644 index 0000000..b7f5e21 --- /dev/null +++ b/app/src/main/java/com/lovejjfg/readhub/view/CustomLayout.java @@ -0,0 +1,151 @@ +/* + * + * Copyright (c) 2017. Joe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.lovejjfg.readhub.view; + +/** + * ReadHub + * Created by Joe at 2017/8/31. + */ + +import android.content.Context; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +public class CustomLayout extends ViewGroup { + //单行显示 + private static final int SINGLE_LINE = 0x01; + //多行显示 + private static final int MULTI_LINE = 0x02; + //显示到下一行 + private static final int NEXT_LINE = 0x03; + //显示样式 + private int type; + //绘制文字最后一行的顶部坐标 + private int lastLineTop; + //绘制文字最后一行的右边坐标 + private float lastLineRight; + + public CustomLayout(Context context) { + super(context); + } + + public CustomLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int childCount = getChildCount(); + int w = MeasureSpec.getSize(widthMeasureSpec); + if (childCount == 2) { + TextView tv = null; + if (getChildAt(0) instanceof TextView) { + tv = (TextView) getChildAt(0); + initTextParams(tv.getText(), tv.getMeasuredWidth(), tv.getPaint()); + } else { + throw new RuntimeException("CustomLayout first child view not a TextView"); + } + + View sencodView = getChildAt(1); + + //测量子view的宽高 + measureChildren(widthMeasureSpec, heightMeasureSpec); + + //两个子view宽度相加小于该控件宽度的时候 + if (tv.getMeasuredWidth() + sencodView.getMeasuredWidth() <= w) { + int width = tv.getMeasuredWidth() + sencodView.getMeasuredWidth(); + //计算高度 + int height = Math.max(tv.getMeasuredHeight(), sencodView.getMeasuredHeight()); + //设置该viewgroup的宽高 + setMeasuredDimension(width, height); + type = SINGLE_LINE; + return; + } + if (getChildAt(0) instanceof TextView) { + //最后一行文字的宽度加上第二个view的宽度大于viewgroup宽度时第二个控件换行显示 + if (lastLineRight + sencodView.getMeasuredWidth() > w) { + setMeasuredDimension(tv.getMeasuredWidth(), tv.getMeasuredHeight() + sencodView.getMeasuredHeight()); + type = NEXT_LINE; + return; + } + + int height = Math.max(tv.getMeasuredHeight(), lastLineTop + sencodView.getMeasuredHeight()); + setMeasuredDimension(tv.getMeasuredWidth(), height); + type = MULTI_LINE; + } + } else { + throw new RuntimeException("CustomLayout child count must is 2"); + } + + + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + if (type == SINGLE_LINE || type == MULTI_LINE) { + TextView tv = (TextView) getChildAt(0); + View v1 = getChildAt(1); + //设置第二个view在Textview文字末尾位置 + tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight()); + int left = (int) lastLineRight; + int top = lastLineTop; + //最后一行的高度 注:通过staticLayout得到的行高不准确故采用这种方式 + int lastLineHeight = tv.getBottom() - tv.getPaddingBottom() - lastLineTop; + //当第二view高度小于单行文字高度时竖直居中显示 + if (v1.getMeasuredHeight() < lastLineHeight) { + top = lastLineTop + (lastLineHeight - v1.getMeasuredHeight()) / 2; + } + v1.layout(left, top, left + v1.getMeasuredWidth(), top + v1.getMeasuredHeight()); + } else if (type == NEXT_LINE) { + View v0 = getChildAt(0); + View v1 = getChildAt(1); + //设置第二个view换行显示 + v0.layout(0, 0, v0.getMeasuredWidth(), v0.getMeasuredHeight()); + v1.layout(0, v0.getMeasuredHeight(), v1.getMeasuredWidth(), v0.getMeasuredHeight() + v1.getMeasuredHeight()); + } + } + + + /** + * 得到Textview绘制文字的基本信息 + * + * @param text Textview的文字内容 + * @param maxWidth Textview的宽度 + * @param paint 绘制文字的paint + */ + private void initTextParams(CharSequence text, int maxWidth, TextPaint paint) { + StaticLayout staticLayout = new StaticLayout(text, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + int lineCount = staticLayout.getLineCount(); + lastLineTop = staticLayout.getLineTop(lineCount - 1); + lastLineRight = staticLayout.getLineRight(lineCount - 1); + } + +} + + diff --git a/app/src/main/java/com/lovejjfg/readhub/view/HomeActivity.kt b/app/src/main/java/com/lovejjfg/readhub/view/HomeActivity.kt index 4b17a7c..2917402 100644 --- a/app/src/main/java/com/lovejjfg/readhub/view/HomeActivity.kt +++ b/app/src/main/java/com/lovejjfg/readhub/view/HomeActivity.kt @@ -24,11 +24,14 @@ import android.os.Bundle import android.support.design.widget.BottomNavigationView import android.support.design.widget.FloatingActionButton import android.support.v7.app.AppCompatActivity +import com.google.firebase.analytics.FirebaseAnalytics import com.lovejjfg.readhub.R import com.lovejjfg.readhub.data.Constants import com.lovejjfg.readhub.databinding.ActivityHomeBinding +import com.lovejjfg.readhub.utils.JumpUitl import com.lovejjfg.readhub.utils.RxBus import com.lovejjfg.readhub.utils.ScrollEvent +import com.lovejjfg.readhub.utils.UIUtil import com.lovejjfg.readhub.view.fragment.DevelopFragment import com.lovejjfg.readhub.view.fragment.HotTopicFragment import com.lovejjfg.readhub.view.fragment.TechFragment @@ -41,14 +44,19 @@ class HomeActivity : AppCompatActivity() { var hotTopicFragment: Fragment? = null var techFragment: Fragment? = null var developFragment: Fragment? = null - var floatButton : FloatingActionButton? = null - var navigation : BottomNavigationView? = null + var floatButton: FloatingActionButton? = null + var navigation: BottomNavigationView? = null + var mFirebaseAnalytics: FirebaseAnalytics? = null private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> - + if (UIUtil.doubleClick()) { + RxBus.instance.post(ScrollEvent()) + return@OnNavigationItemSelectedListener true + } when (item.itemId) { R.id.navigation_home -> { + logEvent("热门服务") fragmentManager.beginTransaction() .show(hotTopicFragment) .hide(techFragment) @@ -57,6 +65,7 @@ class HomeActivity : AppCompatActivity() { return@OnNavigationItemSelectedListener true } R.id.navigation_dashboard -> { + logEvent("科技动态") fragmentManager.beginTransaction() .show(techFragment) .hide(hotTopicFragment) @@ -65,6 +74,7 @@ class HomeActivity : AppCompatActivity() { return@OnNavigationItemSelectedListener true } R.id.navigation_notifications -> { + logEvent("开发资讯") fragmentManager.beginTransaction() .show(developFragment) .hide(hotTopicFragment) @@ -80,10 +90,32 @@ class HomeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + mFirebaseAnalytics?.setCurrentScreen(this, "首页", null) viewBind = DataBindingUtil.setContentView(this, R.layout.activity_home) - navigation = viewBind?.navigation + val navigation1 = viewBind?.navigation + navigation = navigation1 floatButton = viewBind?.fab - viewBind?.navigation?.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) + val toolbar = viewBind?.toolbar + toolbar?.setOnClickListener({ + if (UIUtil.doubleClick()) { + RxBus.instance.post(ScrollEvent()) + } + }) + toolbar?.inflateMenu(R.menu.home) + toolbar?.setOnMenuItemClickListener { + when (it.itemId) { + R.id.home_setting -> { + JumpUitl.jumpSetting(this) + return@setOnMenuItemClickListener true + + } + else -> { + JumpUitl.jumpAbout(this) + return@setOnMenuItemClickListener false + } + } + } + navigation1?.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) if (savedInstanceState == null) { hotTopicFragment = HotTopicFragment() techFragment = TechFragment() @@ -106,5 +138,12 @@ class HomeActivity : AppCompatActivity() { } + fun logEvent(name: String) { + val params = Bundle() + params.putString("tab", name) + mFirebaseAnalytics?.logEvent("tab点击", params) + + } + } diff --git a/app/src/main/java/com/lovejjfg/readhub/view/SettingsActivity.kt b/app/src/main/java/com/lovejjfg/readhub/view/SettingsActivity.kt index 8a973cc..e6aaa74 100644 --- a/app/src/main/java/com/lovejjfg/readhub/view/SettingsActivity.kt +++ b/app/src/main/java/com/lovejjfg/readhub/view/SettingsActivity.kt @@ -21,23 +21,15 @@ package com.lovejjfg.readhub.view import android.annotation.TargetApi import android.content.Context -import android.content.Intent import android.content.res.Configuration -import android.media.Ringtone import android.media.RingtoneManager import android.net.Uri import android.os.Build import android.os.Bundle -import android.preference.ListPreference -import android.preference.Preference -import android.preference.PreferenceActivity -import android.support.v7.app.ActionBar -import android.preference.PreferenceFragment -import android.preference.PreferenceManager -import android.preference.RingtonePreference +import android.preference.* import android.text.TextUtils import android.view.MenuItem - +import com.google.firebase.analytics.FirebaseAnalytics import com.lovejjfg.readhub.R /** @@ -55,6 +47,9 @@ class SettingsActivity : AppCompatPreferenceActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setupActionBar() + fragmentManager.beginTransaction() + .replace(android.R.id.content, GeneralPreferenceFragment()) + .commit() } /** @@ -76,20 +71,17 @@ class SettingsActivity : AppCompatPreferenceActivity() { /** * {@inheritDoc} */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - override fun onBuildHeaders(target: List) { - loadHeadersFromResource(R.xml.pref_headers, target) - } + // @TargetApi(Build.VERSION_CODES.HONEYCOMB) +// override fun onBuildHeaders(target: List) { +// loadHeadersFromResource(R.xml.pref_headers, target) +// } /** * This method stops fragment injection in malicious applications. * Make sure to deny any unknown fragments here. */ override fun isValidFragment(fragmentName: String): Boolean { - return PreferenceFragment::class.java.name == fragmentName - || GeneralPreferenceFragment::class.java.name == fragmentName - || DataSyncPreferenceFragment::class.java.name == fragmentName - || NotificationPreferenceFragment::class.java.name == fragmentName + return GeneralPreferenceFragment::class.java.name == fragmentName } /** @@ -103,79 +95,24 @@ class SettingsActivity : AppCompatPreferenceActivity() { addPreferencesFromResource(R.xml.pref_general) setHasOptionsMenu(true) - // Bind the summaries of EditText/List/Dialog/Ringtone preferences - // to their values. When their values change, their summaries are - // updated to reflect the new value, per the Android Design - // guidelines. - bindPreferenceSummaryToValue(findPreference("example_text")) - bindPreferenceSummaryToValue(findPreference("example_list")) + bindPreferenceSummaryToValue(findPreference(getString(R.string.browser_use))) } override fun onOptionsItemSelected(item: MenuItem): Boolean { val id = item.itemId if (id == android.R.id.home) { - startActivity(Intent(activity, SettingsActivity::class.java)) + activity.finish() return true } return super.onOptionsItemSelected(item) } } - /** - * This fragment shows notification preferences only. It is used when the - * activity is showing a two-pane settings UI. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - class NotificationPreferenceFragment : PreferenceFragment() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - addPreferencesFromResource(R.xml.pref_notification) - setHasOptionsMenu(true) - - // Bind the summaries of EditText/List/Dialog/Ringtone preferences - // to their values. When their values change, their summaries are - // updated to reflect the new value, per the Android Design - // guidelines. - bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone")) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - val id = item.itemId - if (id == android.R.id.home) { - startActivity(Intent(activity, SettingsActivity::class.java)) - return true - } - return super.onOptionsItemSelected(item) - } + override fun onResume() { + super.onResume() + preferenceScreen } - /** - * This fragment shows data and sync preferences only. It is used when the - * activity is showing a two-pane settings UI. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - class DataSyncPreferenceFragment : PreferenceFragment() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - addPreferencesFromResource(R.xml.pref_data_sync) - setHasOptionsMenu(true) - - // Bind the summaries of EditText/List/Dialog/Ringtone preferences - // to their values. When their values change, their summaries are - // updated to reflect the new value, per the Android Design - // guidelines. - bindPreferenceSummaryToValue(findPreference("sync_frequency")) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - val id = item.itemId - if (id == android.R.id.home) { - startActivity(Intent(activity, SettingsActivity::class.java)) - return true - } - return super.onOptionsItemSelected(item) - } - } companion object { @@ -193,47 +130,6 @@ class SettingsActivity : AppCompatPreferenceActivity() { */ private val sBindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, value -> val stringValue = value.toString() - - if (preference is ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list. - val listPreference = preference - val index = listPreference.findIndexOfValue(stringValue) - - // Set the summary to reflect the new value. - preference.setSummary( - if (index >= 0) - listPreference.entries[index] - else - null) - - } else if (preference is RingtonePreference) { - // For ringtone preferences, look up the correct display value - // using RingtoneManager. - if (TextUtils.isEmpty(stringValue)) { - // Empty values correspond to 'silent' (no ringtone). - preference.setSummary(R.string.pref_ringtone_silent) - - } else { - val ringtone = RingtoneManager.getRingtone( - preference.getContext(), Uri.parse(stringValue)) - - if (ringtone == null) { - // Clear the summary if there was a lookup error. - preference.setSummary(null) - } else { - // Set the summary to reflect the new ringtone display - // name. - val name = ringtone.getTitle(preference.getContext()) - preference.setSummary(name) - } - } - - } else { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.summary = stringValue - } true } @@ -255,7 +151,7 @@ class SettingsActivity : AppCompatPreferenceActivity() { sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, PreferenceManager .getDefaultSharedPreferences(preference.context) - .getString(preference.key, "")) + .getBoolean(preference.key, false)) } } } diff --git a/app/src/main/java/com/lovejjfg/readhub/view/fragment/HotTopicAdapter.kt b/app/src/main/java/com/lovejjfg/readhub/view/fragment/HotTopicAdapter.kt index b6abd1b..97692e9 100644 --- a/app/src/main/java/com/lovejjfg/readhub/view/fragment/HotTopicAdapter.kt +++ b/app/src/main/java/com/lovejjfg/readhub/view/fragment/HotTopicAdapter.kt @@ -18,7 +18,6 @@ package com.lovejjfg.readhub.view.fragment -import android.content.Intent import android.databinding.DataBindingUtil import android.os.Bundle import android.support.v4.app.FragmentActivity @@ -35,7 +34,7 @@ import com.lovejjfg.readhub.data.topic.DataItem import com.lovejjfg.readhub.data.topic.NewsArrayItem import com.lovejjfg.readhub.databinding.HolderHotTopicBinding import com.lovejjfg.readhub.databinding.HolderHotTopicItemBinding -import com.lovejjfg.readhub.view.WebActivity +import com.lovejjfg.readhub.utils.JumpUitl import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.subscribeBy @@ -71,10 +70,8 @@ class HotTopicAdapter : PowerAdapter() { rvItem?.layoutManager = LinearLayoutManager(context) val itemAdapter = HotTopicItemAdapter() itemAdapter.setOnItemClickListener { itemView, position, item -> - val i = Intent(context, WebActivity::class.java) - i.putExtra(Constants.URL, t?.newsArray!![position]?.mobileUrl) - - context.startActivity(i) + val mobileUrl = t?.newsArray!![position]?.mobileUrl + JumpUitl.jumpWeb(context, mobileUrl) } rvItem?.adapter = itemAdapter itemAdapter.setList(t?.newsArray) diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..162bea3 --- /dev/null +++ b/app/src/main/res/layout/activity_about.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 4a04473..d5e650b 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -14,11 +14,14 @@ > @@ -45,14 +48,14 @@ app:menu="@menu/navigation"/> - - - - + + + - + diff --git a/app/src/main/res/layout/holder_about_info.xml b/app/src/main/res/layout/holder_about_info.xml new file mode 100644 index 0000000..bc5fece --- /dev/null +++ b/app/src/main/res/layout/holder_about_info.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/holder_hot_topic.xml b/app/src/main/res/layout/holder_hot_topic.xml index 80a49b0..53bbe8a 100644 --- a/app/src/main/res/layout/holder_hot_topic.xml +++ b/app/src/main/res/layout/holder_hot_topic.xml @@ -1,6 +1,7 @@ @@ -22,6 +23,7 @@ android:layout_marginLeft="@dimen/activity_horizontal_margin" android:layout_marginRight="@dimen/activity_horizontal_margin" android:layout_marginBottom="@dimen/activity_horizontal_margin" + app:cardElevation="@{topic.isExband?20:4}" android:foreground="?selectableItemBackground"> diff --git a/app/src/main/res/layout/holder_normal_topic.xml b/app/src/main/res/layout/holder_normal_topic.xml index 9aba855..a1bac1f 100644 --- a/app/src/main/res/layout/holder_normal_topic.xml +++ b/app/src/main/res/layout/holder_normal_topic.xml @@ -41,17 +41,6 @@ tools:text="xxxxxxxxxxx" /> - - diff --git a/app/src/main/res/menu/home.xml b/app/src/main/res/menu/home.xml new file mode 100644 index 0000000..cbfe82b --- /dev/null +++ b/app/src/main/res/menu/home.xml @@ -0,0 +1,34 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 47b3c0b..3e215c9 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -5,6 +5,7 @@ #FF4081 #333333 + #ffffff #4e4e4e #b0b0b0 #656565 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index b59d3d9..1230005 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -5,6 +5,14 @@ 24dp 15sp 12sp - 13sp + 14sp 14sp + + 8dp + 280dp + 280dp + 240dp + 18sp + 16sp + 14sp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0cfd95e..a2c71ee 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,6 +4,12 @@ 科技动态 开发资讯 Settings + 设置 + 关于 + 数据来自 Readhub \n\n + https://readhub.me \n \n + 这不是官方客户端 \n + @@ -11,9 +17,8 @@ General Enable social recommendations - Recommendations for people to contact - based on your message history - + 浏览器 + 是否使用系统自带浏览器浏览 Display name John Smith @@ -76,4 +81,7 @@ Silent Vibrate + 通用 + browser_use + home_first diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7af0b1f..66e5bcf 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 51a5878..a617699 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -1,33 +1,16 @@ - - - - - - - - - + + + + + diff --git a/app/src/main/res/xml/pref_headers.xml b/app/src/main/res/xml/pref_headers.xml index 7861641..0211da5 100644 --- a/app/src/main/res/xml/pref_headers.xml +++ b/app/src/main/res/xml/pref_headers.xml @@ -7,14 +7,4 @@ android:icon="@drawable/ic_info_black_24dp" android:title="@string/pref_header_general"/> -
- -
- diff --git a/build.gradle b/build.gradle index f93574b..3c122e0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.1.4-2' + ext.kotlin_version = '1.1.4-3' ext.gradle_version = '3.0.0-beta3' repositories { jcenter() @@ -10,7 +10,7 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:$gradle_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - + classpath 'com.google.gms:google-services:3.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -23,6 +23,12 @@ allprojects { } } +subprojects { project -> + + apply from: + rootProject.getRootDir().getAbsolutePath() + "/util.gradle" +} + task clean(type: Delete) { delete rootProject.buildDir } diff --git a/gradle.properties b/gradle.properties index 64c4ede..ab819b2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,5 +20,5 @@ BUILD_TOOLS_VERSION=26.0.1 TARGET_SDK_VERSION=26 MIN_SDK_VERSION=21 -SUPPORT_V4_VERSION=26.0.1 -SUPPORT_V7_VERSION=26.0.1 \ No newline at end of file +SUPPORT_V4_VERSION=26.0.2 +SUPPORT_V7_VERSION=26.0.2 \ No newline at end of file diff --git a/util.gradle b/util.gradle new file mode 100644 index 0000000..5acef8e --- /dev/null +++ b/util.gradle @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017. Joe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +def initGradleEnvironment() { + + Properties properties = new Properties() + boolean isHasFile = false + File propertyFile = new File(rootDir.getAbsolutePath() + "/local.properties") + if (propertyFile.exists()) { + isHasFile = true + properties.load(propertyFile.newDataInputStream()) + } + //gradle就是gradle对象。它默认是Settings和Project的成员变量。可直接获取 + //ext前缀,表明操作的是外置属性。api是一个新的属性名。前面说过,只在 + //第一次定义或者设置它的时候需要ext前缀 + gradle.ext.isHasFile = isHasFile + gradle.ext.user = properties.getProperty('bintray.user') + gradle.ext.apikey = properties.getProperty('bintray.apikey') +} + +initGradleEnvironment() + +String initTag() { + try { + def versionName = 'git describe --abbrev=0 --tags'.execute([], project.rootDir).text.trim() +// def indexOf = versionName.indexOf("-", 0) +// versionName = indexOf != -1 ? versionName.substring(0, indexOf) : versionName + if (version == null || "" == versionName) { + return "v0.0.0" + } + println versionName + return versionName + } catch (e) { + println e.toString() + return "v1.0.0" + } + +} + +int initCount() { + try { + return 100 + + Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim()) + } catch (e) { + println e.toString() + return 100 + } +} + +ext { + gitTag = initTag() + gitCommitCount = initCount() +} + +