Kotlin学习的简易练手

目录

Kotlin学习的简易练手

一、AndroidStudio的gradle配置(重点部分都有双斜杠注释)

1、Module的gradle配置(重点是引入Kotlin以及Kotlin-extention)

2、Project的gradle配置

二、具体的相关代码

主Activity以及XML

圆形头像类以及attrs.xml:

okhttp3.0封装类

Kotlin数据bean类:

给RecyclerView的Adapter类和XML:

最后即接口类和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还是很好用的,多联系以下就会顺手些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值