安卓开发之Kotlin和java双实现仿qq空间下拉图片拉伸
Posted Losileeya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓开发之Kotlin和java双实现仿qq空间下拉图片拉伸相关的知识,希望对你有一定的参考价值。
先不扯淡看今天要实现的效果:
话说使用Kotlin实现安卓功能,那我们还是要做一点准备工作,so,你得加一点插件到eclipse或android studio。然并卵,你现在还在使用eclipse开发的话我只能提供地址Kotlin Plugin for Eclipse,然后我使用的还是死丢丢。
死丢丢(android studio)集成kotlin安卓开发
要使用android studio开发kotlin的安卓app,那么你必须有开发kotlin的环境:
Kotlin插件。打开Android Studio的首选项的搜索插件面板,使用搜索功能查询Kotlin插件,安装完成并重启即可。
但是你要使用Kotlin开发安卓程序的话还需要Kotlin Extension For Android,方法也是一样的
在插件列表中选择或者搜索Kotlin Extensions For Android并点击右边窗口的Install Plugin按钮:
哈哈,你也可以参考:
Getting started with Android and Kotlin
Kotlin Android Extensions
给你提个tip:如果你觉得在android studio里面install 这两个插件很慢,动不动失败的话,那么这里给你提供一离线地址:(kotlin和kotlin for android),其实家里网速不好我就是离线下载这么干的,在公司呢就是在线弄的,以后一般的插件你都可以往这里面去离线下载。
是不是基本的插件装完了就可以开发了,个人推荐你可以再加一个:
Anko 插件
看图:
离线下载:
使用方法呢,看下图:
1. 把.java文件转成.kt文件:
当然你也可以按住 Ctrl+alt+shift+K的组合键来使用。
2. 把java的安卓项目变成Kotlin项目:
3. 新建kotlin文件
再来注意下gradle文件:
apply plugin: ‘kotlin-android’
apply plugin: ‘kotlin-android-extensions’sourceSets {
main.java.srcDirs += ‘src/main/kotlin’
}dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
compile “org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version”
}buildscript {
ext.kotlin_version = ‘1.0.1-2’
repositories {
mavenCentral()
}
dependencies {
classpath “org.jetbrains.kotlin:kotlin-gradle- plugin:$kotlin_version”
}
}
repositories {
mavenCentral()
}
思路
其实PullToZoomListView的实现原理很简单:就是一个listView加header,然后header是把图片作为填充内容,通过滚动和触摸事件来改变图片的大小,主要是在case MotionEvent.ACTION_MOVE:代码段中判断向下滑动的偏移量,根据这个来改变listview headerView内容区域的高度,并且在手指放开的那一刻,停止缩放,启用一个动画来使HeaderView平滑的恢复到放大之前的状态。
java实现仿qq空间下拉图片拉伸
我们先来看PullToZoomListView的实现:
package com.example.pulltozoomlistview.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import com.example.pulltozoomlistview.R;
public class PullToZoomListView extends ListView {
private ImageView mImageView;
// 初始高度
private int mImageViewHeight = -1;
// 最大拉伸高度
private int mDrawableMaxHeight = -1;
public PullToZoomListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 设置拉伸的图片
*
* @param imageView
*/
public void setPullToZoomImageView(ImageView imageView) {
this.mImageView = imageView;
// 设置伸缩类型 -- 居中填充
this.mImageView.setScaleType(ScaleType.CENTER_CROP);
}
/**
* 初始化图片加载进来最初的高度
*
*/
public void setViewBounds() {
if (mImageViewHeight == -1) {
mImageViewHeight = mImageView.getHeight();
if (mImageViewHeight < 0) {
mImageViewHeight = getContext().getResources()
.getDimensionPixelSize(R.dimen.size_default);
}
}
}
/**
* 滑动过头的时候回调
*/
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,int scrollY, int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
// 控制ImageView的高度不断增加
boolean isCollapse = resizeOverScrollBy(deltaY);
// return true:下拉到边界的某个地方的时候不再往下拉
return isCollapse ? true : super.overScrollBy(deltaX, deltaY, scrollX,scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,maxOverScrollY, isTouchEvent);
}
/**
* 监听ListView滑动
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
// 获得ImageView的父控件
View header = (View) mImageView.getParent();
if (header.getTop() < 0 && mImageView.getHeight() > mImageViewHeight) {
// 减小ImageView的高度 -- 不能超过图片最原始的高度
mImageView.getLayoutParams().height = Math.max(
mImageView.getHeight() + header.getTop(), mImageViewHeight);
// ImageView所在的容器的高度也要变化:getTop--->0
header.layout(header.getLeft(), 0, header.getRight(),
header.getHeight());
mImageView.requestLayout();
}
}
private boolean resizeOverScrollBy(int deltaY) {
// 下拉的过程当中,不断地控制ImageView的高度
/**
* deltaY:是在超出滑动的时候每毫秒滑动的距离 -- 增量 (-往下拉过渡,+往上拉过渡) 大小:根据用户滑动的速度决定 一般滑动的速度
* -50~50
*/
if (deltaY < 0) {
// 下拉过渡,不断增加ImageView的高度,deltay是负数,增加高度就是减去
mImageView.getLayoutParams().height = mImageView.getHeight()
- deltaY;
// View重新调整宽高
mImageView.requestLayout(); // onMeasure-->onLayout
} else {
// 上拉过渡,不断减小ImageView的高度,deltay是正数,减小高度还是减去
if (mImageView.getHeight()>mImageViewHeight) {
mImageView.getLayoutParams().height = Math.max(mImageView.getHeight() - deltaY, mImageViewHeight);
// View重新调整宽高
mImageView.requestLayout(); // onMeasure-->onLayout
}
}
return false;
}
/**
* 监听触摸 -- 松开手
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
// 判断
if (ev.getAction()== MotionEvent.ACTION_UP) {
// 开启回弹的动画
ResetAnimation animation=new ResetAnimation(mImageView,mImageViewHeight);
animation.setDuration(300);
mImageView.startAnimation(animation);
}
return super.onTouchEvent(ev);
}
public class ResetAnimation extends Animation{
private ImageView mView;
private int targetHeight;
// 动画执行前的高度
private int originalHeight;
// 高度差
private int extraHeight;
public ResetAnimation(ImageView mImageView,int targetHeight) {
this.mView=mImageView;
this.targetHeight=targetHeight;
this.originalHeight=mImageView.getHeight();
extraHeight=originalHeight-targetHeight;
}
/**
* 动画不断地执行的时候会回调该方法
* interpolatedTime:范围是0
* 0ms-------------->300ms
* 当前的图片高度--->动画执行之前的高度-高度差*interpolatedTime
* extraHeight------>0
*/
@Override
protected void applyTransformation(float interpolatedTime,Transformation t) {
mView.getLayoutParams().height=(int) (originalHeight-extraHeight*interpolatedTime);
mView.requestLayout();
super.applyTransformation(interpolatedTime, t);
}
}
}
MainActivity的简单使用PullToZoomListView
package com.example.pulltozoomlistview;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import com.example.pulltozoomlistview.view.PullToZoomListView;
public class MainActivity extends AppCompatActivity {
private PullToZoomListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
if(Build.VERSION.SDK_INT>=21){
getSupportActionBar().setElevation(0f);
}
lv=(PullToZoomListView) findViewById(R.id.main_lv);
View header=View.inflate(this, R.layout.layout_lv_header, null);
lv.addHeaderView(header);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
new String[]{"腾讯","阿里巴巴","百度","新浪","c语言","java","php","FaceBook","Twiter","xml","html"});
lv.setAdapter(adapter);
ImageView iv=(ImageView) header.findViewById(R.id.header_img);
lv.setPullToZoomImageView(iv);
}
// 当界面显示出来的时候回调
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
lv.setViewBounds();
}
}
}
Kotlin实现仿qq空间下拉图片拉伸
同样我们先来看使用kotlin语言来实现PullToZoomListView:
package com.example.pulltozoom.view
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.animation.Animation
import android.view.animation.Transformation
import android.widget.ImageView
import android.widget.ImageView.ScaleType
import android.widget.ListView
import com.example.pulltozoom.R
open class PullToZoomListView(context: Context, attrs: AttributeSet) : ListView(context, attrs) {
private var mImageView: ImageView? = null
// 初始高度
private var mImageViewHeight = -1
// 最大拉伸高度
private val mDrawableMaxHeight = -1
/**
* 设置拉伸的图片
* @param imageView
*/
fun setPullToZoomImageView(imageView: ImageView) {
this.mImageView = imageView
// 设置伸缩类型 -- 居中填充
this.mImageView!!.scaleType = ScaleType.CENTER_CROP
}
/**
* 初始化图片加载进来最初的高度
*/
fun setViewBounds() {
if (mImageViewHeight == -1) {
mImageViewHeight = mImageView!!.height
if (mImageViewHeight < 0) {
mImageViewHeight = context.resources.getDimensionPixelSize(R.dimen.size_default)
}
}
}
/**
* 滑动过头的时候回调
*/
override fun overScrollBy(deltaX: Int, deltaY: Int, scrollX: Int,scrollY: Int, scrollRangeX: Int, scrollRangeY: Int, maxOverScrollX: Int, maxOverScrollY: Int, isTouchEvent: Boolean): Boolean {
// 控制ImageView的高度不断增加
val isCollapse = resizeOverScrollBy(deltaY)
// return true:下拉到边界的某个地方的时候不再往下拉
return if (isCollapse)
true
else
super.overScrollBy(deltaX, deltaY, scrollX,
scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,
maxOverScrollY, isTouchEvent)
}
/**
* 监听ListView滑动
*/
override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
super.onScrollChanged(l, t, oldl, oldt)
// 获得ImageView的父控件
val header = mImageView!!.parent as View
if (header.top < 0 && mImageView!!.height > mImageViewHeight) {
// 减小ImageView的高度 -- 不能超过图片最原始的高度
mImageView!!.layoutParams.height = Math.max(
mImageView!!.height + header.top, mImageViewHeight)
// ImageView所在的容器的高度也要变化:getTop--->0
header.layout(header.left, 0, header.right,
header.height)
mImageView!!.requestLayout()
}
}
private fun resizeOverScrollBy(deltaY: Int): Boolean {
// 下拉的过程当中,不断地控制ImageView的高度
/**
* deltaY:是在超出滑动的时候每毫秒滑动的距离 -- 增量 (-往下拉过渡,+往上拉过渡) 大小:根据用户滑动的速度决定 一般滑动的速度
* -50~50
*/
if (deltaY < 0) {
// 下拉过渡,不断增加ImageView的高度,deltay是负数,增加高度就是减去
mImageView!!.layoutParams.height = mImageView!!.height - deltaY
// View重新调整宽高
mImageView!!.requestLayout() // onMeasure-->onLayout
} else {
// 上拉过渡,不断减小ImageView的高度,deltay是正数,减小高度还是减去
if (mImageView!!.height > mImageViewHeight) {
mImageView!!.layoutParams.height = Math.max(mImageView!!.height - deltaY, mImageViewHeight)
// View重新调整宽高
mImageView!!.requestLayout() // onMeasure-->onLayout
}
}
return false
}
/**
* 监听触摸 -- 松开手
*/
override fun onTouchEvent(ev: MotionEvent): Boolean {
// 判断
if (ev.action == MotionEvent.ACTION_UP) {
// 开启回弹的动画
val animation = ResetAnimation(mImageView!!, mImageViewHeight)
animation.duration = 300
mImageView!!.startAnimation(animation)
}
return super.onTouchEvent(ev)
}
inner class ResetAnimation(private val mView: ImageView, private val targetHeight: Int) : Animation() {
// 动画执行前的高度
private val originalHeight: Int
// 高度差
private val extraHeight: Int
init {
this.originalHeight = mView.height
extraHeight = originalHeight - targetHeight
}
/**
* 动画不断地执行的时候会回调该方法
* interpolatedTime:范围是0
* 0ms-------------->300ms
* 当前的图片高度--->动画执行之前的高度-高度差 *interpolatedTime
* extraHeight------>0
*/
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
mView.layoutParams.height = (originalHeight - extraHeight * interpolatedTime).toInt()
mView.requestLayout()
super.applyTransformation(interpolatedTime, t)
}
}
}
接下来使用kotlin实现MainActivity:
package com.example.pulltozoom
import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.layout_lv_header.*
/**
* QQ空间之打造个性化可拉伸头部控件
*/
open class MainActivity : AppCompatActivity() {
// private var lv: PullToZoomListView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar!!.hide()
//以下代码用于去除阴影
if(Build.VERSION.SDK_INT>=21){
supportActionBar!!.elevation=0f
}
// lv = findViewById(R.id.main_lv) as PullToZoomListView?
val header = View.inflate(this, R.layout.layout_lv_header, null)
main_lv!!.addHeaderView(header)
val adapter = ArrayAdapter(this,
android.R.layout.simple_list_item_1,
arrayOf("腾讯","阿里巴巴","百度","新浪","c语言","java","php","FaceBook","Twiter","xml","html"))
main_lv!!.adapter = adapter
//val iv = header.findViewById(R.id.header_img) as ImageView
main_lv!!.setPullToZoomImageView(header_img)
}
// 当界面显示出来的时候回调
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) {
main_lv!!.setViewBounds()
}
}
}
kotlin Extensions使用总结:
Using Kotlin Android Extensions要点:
1. apply plugin: ‘kotlin-android-extensions’
2. activity_main绑定xml在activity里这样写:
import kotlinx.android.synthetic.main.activity_main.view.*
3. xml里面的控件不再需要findViewById(),直接用id代替空间来操作
java版和kotlin版demo传送门(网速不好,明天上传):PullToZoom.rar
以上是关于安卓开发之Kotlin和java双实现仿qq空间下拉图片拉伸的主要内容,如果未能解决你的问题,请参考以下文章