目录
一、AndroidStudio的gradle配置(重点部分都有双斜杠注释)
1、Module的gradle配置(重点是引入Kotlin以及Kotlin-extention)
最后即接口类和FloatingActionButton简单重写的Behavior:
参考饭否的项目练手的:Kotlin饭否
Kotlin学习的简易练手
一、AndroidStudio的gradle配置(重点部分都有双斜杠注释)
1、Module的gradle配置(重点是引入Kotlin以及Kotlin-extention)
apply plugin: 'com.android.application'
//kotlin
apply plugin: 'kotlin-android'
//kotlinx-extention
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.ktdemo"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:27.1.1'
//引入CardView
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
//design
implementation 'com.android.support:design:27.1.1'
//okhttp3.0
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
//gson
implementation 'com.google.code.gson:gson:2.8.5'
//picasso
implementation 'com.squareup.picasso:picasso:2.71828'
}
apply plugin: 'kotlin-android-extensions'
2、Project的gradle配置
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
//kotlin
ext.kotlin_version ='1.2.30'
repositories {
google()
jcenter()
mavenCentral()//add repositories because greendao needed
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
//kotlin
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
二、具体的相关代码
主Activity以及XML
package com.example.ktdemo.news
import android.app.DatePickerDialog
import android.content.Intent
import android.os.Bundle
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import com.example.ktdemo.R
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_ui.*
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Response
import java.io.IOException
import java.sql.Date
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
class UIActivity : AppCompatActivity(), OnRecyclerViewOnClickListener {
override fun onItemClick(view: View, position: Int) {
}
private var postsList = ArrayList<FanfouPost>()
private var y: Int = 2015
private var m: Int = 9
private var d: Int = 5
private var adapter: RVAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ui)
initView()
val date = SimpleDateFormat("yyyy-MM-dd")
val formatStr = date.format(Date())
//获取数据
val url: String = "http://blog.fanfou.com/digest/json/2018-02-11.daily.json"
Log.d("zbv", "uri=$url")
//使用匿名内部类(接口)
HttpUtilsForKotlin.getokHttpAsync(OkHttpClient(), url, object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
Log.d("zbv", "请求失败")
}
override fun onResponse(call: Call?, response: Response?) {
val result = response!!.body()!!.string()
Log.d("zbv", "result=$result")
val gson = Gson()
val javabeans = gson.fromJson<KotlinBeanGson>(result, KotlinBeanGson::class.java)
Log.d("zbv", "javabeans$javabeans")
val messages = javabeans.msgs
for (message: KotlinBeanGson.Message in messages) {
val fanfou = FanfouPost(message.avatar, message.realname, message.msg, message.time, "")
postsList.add(fanfou)
}
runOnUiThread(Runnable {
adapter = RVAdapter(this@UIActivity, postsList)
recycler_view.adapter = adapter
adapter!!.setOnItemClickListener(this@UIActivity)
})
}
})
floating_actionBar.setOnClickListener {
val c = Calendar.getInstance()
val dialog: DatePickerDialog = DatePickerDialog(
this, DatePickerDialog.OnDateSetListener { dataPicker, year, month, day ->
y = year
m = month
d = day
}, y, m, d)
}
}
fun initView() {
//设置rv中item的排列方式:竖排
recycler_view.layoutManager = LinearLayoutManager(this)
//设置下拉刷新的进度圆颜色和尺寸
swipe_refresh_layout.setColorSchemeColors(resources.getColor(R.color.colorAccent))
swipe_refresh_layout.setSize(SwipeRefreshLayout.DEFAULT)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
this.menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item!!.itemId) {
R.id.action_about -> {
val intent = Intent(this, AboutActiivty::class.java)
startActivity(intent)
}
}
return true
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".news.UIActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/floating_actionBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:src="@mipmap/ic_launcher_round"
app:layout_behavior="com.example.ktdemo.news.FabHideOnScroll" />
</android.support.design.widget.CoordinatorLayout>
圆形头像类以及attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleImageView">
<attr name="civ_border_width" format="dimension" />
<attr name="civ_border_color" format="color" />
<attr name="civ_border_overlay" format="boolean" />
<attr name="civ_fill_color" format="color" />
</declare-styleable>
</resources>
package com.example.ktdemo.news;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.example.ktdemo.R;
/**
* Created by lizhaotailang on 2016/7/6.
*/
public class CircleImageView extends ImageView {
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 2;
private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
private static final boolean DEFAULT_BORDER_OVERLAY = false;
private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
private final Paint mBorderPaint = new Paint();
private final Paint mFillPaint = new Paint();
private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private int mFillColor = DEFAULT_FILL_COLOR;
private Bitmap mBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;
private float mDrawableRadius;
private float mBorderRadius;
private ColorFilter mColorFilter;
private boolean mReady;
private boolean mSetupPending;
private boolean mBorderOverlay;
private boolean mDisableCircularTransformation;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
a.recycle();
init();
}
private void init() {
super.setScaleType(SCALE_TYPE);
mReady = true;
if (mSetupPending) {
setup();
mSetupPending = false;
}
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}
@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mDisableCircularTransformation) {
super.onDraw(canvas);
return;
}
if (mBitmap == null) {
return;
}
if (mFillColor != Color.TRANSPARENT) {
canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);
}
canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);
if (mBorderWidth != 0) {
canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setup();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(@ColorInt int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public void setBorderColorResource(@ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}
public int getFillColor() {
return mFillColor;
}
public void setFillColor(@ColorInt int fillColor) {
if (fillColor == mFillColor) {
return;
}
mFillColor = fillColor;
mFillPaint.setColor(fillColor);
invalidate();
}
public void setFillColorResource(@ColorRes int fillColorRes) {
setFillColor(getContext().getResources().getColor(fillColorRes));
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
public boolean isBorderOverlay() {
return mBorderOverlay;
}
public void setBorderOverlay(boolean borderOverlay) {
if (borderOverlay == mBorderOverlay) {
return;
}
mBorderOverlay = borderOverlay;
setup();
}
public boolean isDisableCircularTransformation() {
return mDisableCircularTransformation;
}
public void setDisableCircularTransformation(boolean disableCircularTransformation) {
if (mDisableCircularTransformation == disableCircularTransformation) {
return;
}
mDisableCircularTransformation = disableCircularTransformation;
initializeBitmap();
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
initializeBitmap();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
initializeBitmap();
}
@Override
public void setImageResource(@DrawableRes int resId) {
super.setImageResource(resId);
initializeBitmap();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
initializeBitmap();
}
@Override
public void setColorFilter(ColorFilter cf) {
if (cf == mColorFilter) {
return;
}
mColorFilter = cf;
applyColorFilter();
invalidate();
}
@Override
public ColorFilter getColorFilter() {
return mColorFilter;
}
private void applyColorFilter() {
if (mBitmapPaint != null) {
mBitmapPaint.setColorFilter(mColorFilter);
}
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void initializeBitmap() {
if (mDisableCircularTransformation) {
mBitmap = null;
} else {
mBitmap = getBitmapFromDrawable(getDrawable());
}
setup();
}
private void setup() {
if (!mReady) {
mSetupPending = true;
return;
}
if (getWidth() == 0 && getHeight() == 0) {
return;
}
if (mBitmap == null) {
invalidate();
return;
}
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mFillPaint.setStyle(Paint.Style.FILL);
mFillPaint.setAntiAlias(true);
mFillPaint.setColor(mFillColor);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
mBorderRect.set(calculateBounds());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
mDrawableRect.set(mBorderRect);
if (!mBorderOverlay) {
mDrawableRect.inset(mBorderWidth, mBorderWidth);
}
mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
applyColorFilter();
updateShaderMatrix();
invalidate();
}
private RectF calculateBounds() {
int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
int sideLength = Math.min(availableWidth, availableHeight);
float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
float top = getPaddingTop() + (availableHeight - sideLength) / 2f;
return new RectF(left, top, left + sideLength, top + sideLength);
}
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}
okhttp3.0封装类
package com.example.ktdemo.news
import okhttp3.*
/**
* @author qzx
* @time 2018/9/25 19:03
*/
object HttpUtilsForKotlin {
/**
* GET方式请求HTTP
* */
fun getokHttpAsync(okHttpClient: OkHttpClient, url: String, callback: Callback) {
//首先获取请求对象Request
val request: Request = Request.Builder().url(url).build()
//然后获取到Call对象
val call: Call = okHttpClient.newCall(request)
//使用异步的入队方式(execute是同步)
call.enqueue(callback)
}
/**
* POST方式请求HTTP
* </br>
* 使用一个Map传递post参数
* */
fun postokHttpAsync(okHttpClient: OkHttpClient, url: String, paraMap: Map<String, String>, callback: Callback) {
val builder: FormBody.Builder = FormBody.Builder()
val iterator = paraMap.entries.iterator()
while (iterator.hasNext()) {
val entry = iterator.next()
builder.add(entry.key, entry.value)
}
val requestBody: RequestBody = builder.build()
val request = Request.Builder().url(url).post(requestBody).build()
val call = okHttpClient.newCall(request)
call.enqueue(callback)
}
}
Kotlin数据bean类:
package com.example.ktdemo.news
/**
* @author qzx
* @time 2018/9/26 16:53
*/
class KotlinBeanGson(val shift:String,val shift_cn:String,val date:String,val msgs:List<Message>){
inner class Message(val realname:String,val avatar:String,val msg:String,val time:String){
override fun toString(): String {
return "Message(realname='$realname', avatar='$avatar', msg='$msg', time='$time')"
}
}
override fun toString(): String {
return "KotlinBeanGson(shift='$shift', shift_cn='$shift_cn', date='$date', msgs=$msgs)"
}
}
//-------------------------------------------------------
package com.example.ktdemo.news
/**
* @author qzx
* @time 2018/9/18 17:59
*
* (val avatarUrl: String, val author: String, val content: String, val time: String, val imgUrl: String)
*/
data class FanfouPost(var avatarUrl: String, var author: String, var content: String,
var time: String, var imgUrl: String)
/*
class FanfouPost {
var avatarUrl: String? = null
var author: String? = null
var content: String? = null
var time: String? = null
var imgUrl: String? = null
constructor(avatarUrl: String, author: String, content: String?, time: String, imgUrl: String) {
this.avatarUrl = avatarUrl
this.author = author
this.content = content
this.time = time
this.imgUrl = imgUrl
}
}*/
给RecyclerView的Adapter类和XML:
package com.example.ktdemo.news
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.ktdemo.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.fanfou_item_layout.view.*
/**
* @author qzx
* @time 2018/9/26 14:36
*/
class RVAdapter(val context: Context, val list: List<FanfouPost>) :
RecyclerView.Adapter<RVAdapter.FanfouPostsViewHolder>() {
private var listener: OnRecyclerViewOnClickListener? = null
fun setOnItemClickListener(listener: OnRecyclerViewOnClickListener) {
this.listener = listener
}
init {
//可用于初始化使用主构造器中的参数
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FanfouPostsViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.fanfou_item_layout, parent, false)
return FanfouPostsViewHolder(view, listener!!)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: FanfouPostsViewHolder, position: Int) {
val item = list[position]
Picasso.get().load(item.avatarUrl).placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher).into(holder.itemView.avatar)
if (item.imgUrl.isNullOrEmpty()) {
holder.itemView.iv_main.visibility = View.INVISIBLE
} else {
holder.itemView.iv_main.visibility = View.VISIBLE
}
holder.itemView.tv_author.text = item.author
holder.itemView.tv_content.text = Html.fromHtml(item.content).toString()
holder.itemView.tv_time.text = item.time
}
inner class FanfouPostsViewHolder(itemView: View, listener: OnRecyclerViewOnClickListener)
: RecyclerView.ViewHolder(itemView), View.OnClickListener {
//internal模块类使用有效
private val listener: OnRecyclerViewOnClickListener = listener
init {
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
listener.onItemClick(v!!, layoutPosition)
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingRight="16dp"
android:paddingLeft="16dp">
<com.example.ktdemo.news.CircleImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/avatar"
android:layout_marginRight="16dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_author"
android:textSize="16sp"
android:textStyle="bold"
android:gravity="center_vertical"
android:layout_marginTop="8dp" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/iv_main"
android:src="@mipmap/ic_launcher_round"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_content"
android:layout_marginTop="8dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_time"
android:layout_marginTop="8dp"
android:gravity="start" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
最后即接口类和FloatingActionButton简单重写的Behavior:
package com.example.ktdemo.news;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
/**
* @author qzx
* @time 2018/9/18 17:54
*/
public class FabHideOnScroll extends FloatingActionButton.Behavior {
public FabHideOnScroll(Context context, AttributeSet attr){
super();
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
// child -> Floating Action Button
if (dyConsumed > 0){
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
int fabBottomMargin = layoutParams.bottomMargin;
child.animate().translationY(child.getHeight() + fabBottomMargin).setInterpolator(new LinearInterpolator()).start();
} else if (dyConsumed < 0){
child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
}
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
}
package com.example.ktdemo.news
import android.view.View
/**
* @author qzx
* @time 2018/9/18 17:57
*/
interface OnRecyclerViewOnClickListener {
fun onItemClick(view: View, position: Int)
}
这次简单的学习使用Kotlin完结,感觉Kotlin还是很好用的,多联系以下就会顺手些。