仿系统原生天气毛坯版

原生的效果图是这样,自己写的比较粗糙


original_weather.gif

刚开始看到这的时候,我还想着自定义一个viewGroup。后来写出来感觉效果太生硬,就是根据触摸事件来移动。

然后过了一段时间,我想着看下原生的咋弄的,就用eclipse带的那个布局查看器,看了下它的布局,发现了一个weatherScrollView的自定义控件,里边就是个线性布局包裹着所有的控件了,这这和我想的差距有点大啊。。

不过仔细想想,这滑动的这部分好像也就是一个线性布局,只不过有一部分是隐藏的,慢慢放出来而已。
有了思路就好解决了。先弄几个粗的布局,如下




    
        
            
                
                
            
            
                
            
        
        
            
            
        
        
        
            
        
    

    

        

            

            

            
        


        

            
            
        


        

        
            

        
    

    



android:id="@+id/layout333" 这个里边的第一个布局tv_hidden就是默认隐藏的东西了。当然了原生的这里不是这个,我们就用个textview替代下。

核心代码如下,很简单,就是在滚动的时候修改下那个tv_hidden的marginTop

import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import android.widget.ScrollView
import com.charliesong.demo0327.R
/**
 * Created by charlie.song on 2018/4/27.
 */
class WeatherScrollView:ScrollView{
    constructor(context: Context?) : super(context){
        initSome()
    }
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs){
        initSome()
    }
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){
        initSome()
    }
    private fun initSome(){
        dp220= (context.resources.displayMetrics.density*220).toInt();
    }
   lateinit var hiddenView: View;
    var dp220=220;//这个就是那个默认隐藏的控件的高度,在xml里这个控件初始的时候设置了android:layout_marginTop="-220dp",也就是不可见的
    override fun draw(canvas: Canvas?) {
        super.draw(canvas) //简单看下scrollview的代码就可以知道,滚动的时候它会调用这个修改子控件的位置
if(!touch){
            return
        }
        hiddenView=findViewById(R.id.tv_hidden) //那个默认不可见的布局,也即是marginTop为负的控件本身的高度
        var result=scrollY-dp220;
        if(result<=0){
          var params=  hiddenView.layoutParams as LinearLayout.LayoutParams
            params.topMargin=result //不停的修改topMargin直到完全可见
            hiddenView.layoutParams=params
        }
        onScrollChangeListener?.run {
            onScroollY(scrollY.toFloat()) //这回掉就是为了处理下上边的动画,
        }
    }
var touch=false
    override fun onTouchEvent(ev: MotionEvent): Boolean {
        var result= super.onTouchEvent(ev)
 if(ev.action==MotionEvent.ACTION_DOWN){
            touch=true
        }
        if(ev.action==MotionEvent.ACTION_UP||ev.action==MotionEvent.ACTION_CANCEL){
touch=false
            val dp180=dp220*180/220; //180是我们默认设置的滚动这部分距离最高点的padding。滚动一半我们就还原,滚动超过一半就让它滚到顶部
             if(scrollY

接口在这里

interface ScrollChangeListener{
    abstract  fun onScroollY(yScroll:Float)
}

代码中使用也简单,就是处理下动画,如果不需要处理,那java里啥也不用写了
实在懒得处理,就简单弄了下平移x和y.看下效果而已

    var dp180=180f
    var intervalLoation=0;
    var intervalDate=0
    var intervalTemperature=0

    override fun onCreate(arg0: Bundle?) {
        super.onCreate(arg0)
        setContentView(R.layout.activity_weather2)
        dp180=resources.displayMetrics.density*180
        sv.onScrollChangeListener=object :ScrollChangeListener{
            override fun onScroollY(yScroll: Float) {
                if(intervalLoation==0){
                    intervalLoation=layout_location.left
                    intervalDate=layout_date.left
                    intervalTemperature=layout_temperature.left
                }
                if(yScroll

你可能感兴趣的:(仿系统原生天气毛坯版)