美文网首页
仿系统原生天气毛坯版

仿系统原生天气毛坯版

作者: 有点健忘 | 来源:发表于2018-04-28 11:41 被阅读14次

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


original_weather.gif

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

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

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

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#1190df"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/rela_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <RelativeLayout
            android:id="@+id/layout_location_date"
            android:layout_width="match_parent"
            android:background="#1190df"
            android:layout_height="100dp">
            <LinearLayout
                android:id="@+id/layout_location"
                android:layout_centerHorizontal="true"
                android:orientation="horizontal"
                android:layout_above="@+id/layout_date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageView
                    android:src="@drawable/ic_launcher_background"
                    android:layout_width="20dp"
                    android:layout_height="20dp" />
                <TextView
                    android:id="@+id/tv_location"
                    android:text="静安"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
            <LinearLayout
                android:id="@+id/layout_date"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <TextView
                    android:text="4月27日,星期五 14:00"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </RelativeLayout>
        <LinearLayout
            android:id="@+id/layout_temperature"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/layout_location_date"
            android:orientation="horizontal"
            android:gravity="center_vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <ImageView
                android:src="@drawable/adp_global_launcher_icon"
                android:layout_width="25dp"
                android:layout_height="25dp" />
            <TextView
                android:text="26℃"
                android:textSize="35sp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
        <TextView
            android:id="@+id/tv_weather"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/layout_temperature"
            android:text="多云"
            android:textSize="17sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <LinearLayout
            android:id="@+id/layout_aqi"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/tv_weather"
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <TextView
                android:text="AQI 103(轻度污染)"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </RelativeLayout>
<com.charliesong.demo0327.weather.WeatherScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/sv"
    android:overScrollMode="never"
    android:scrollbars="none"
    android:layout_marginTop="180dp"
    android:orientation="vertical" >
    <LinearLayout
        android:orientation="vertical"
        android:paddingTop="180dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/layout222"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:text="every hour" />

            <ImageView
                android:layout_width="match_parent"
                android:adjustViewBounds="true"
                android:layout_height="wrap_content"
                android:src="@drawable/per_hour_temperature" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:text="every day" />
        </LinearLayout>


        <LinearLayout
            android:id="@+id/layout333"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/tv_hidden"
                android:layout_width="match_parent"
                android:text="200dp是我"
                android:layout_marginTop="-220dp"
                android:textSize="33sp"
                android:gravity="center"
                android:layout_height="220dp"
                android:background="@drawable/per_hour_temperature" />
            <TextView
                android:id="@+id/layout_show"
                android:layout_width="match_parent"
                android:text="100dp是我"
                android:textSize="33sp"
                android:gravity="center"
                android:layout_height="100dp"
                android:background="@drawable/day_weather" />
        </LinearLayout>


        <LinearLayout
        android:id="@+id/layout444"
       android:background="#440000ff"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:text="layout4......." />
            <ImageView
                android:layout_width="match_parent"
                android:adjustViewBounds="true"
                android:layout_height="wrap_content"
                android:src="@drawable/today_intro" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:text="layout4 last" />
    </LinearLayout>

    </LinearLayout>
</com.charliesong.demo0327.weather.WeatherScrollView>

</FrameLayout>

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<dp180){
                 if(scrollY<dp180/2){
                     smoothScrollTo(0,0)
                 }else{
                     smoothScrollTo(0,dp180)
                 }
                 onScrollChangeListener?.run {
                     onScroollY(scrollY.toFloat())
                 }
            }
        }
        return result
    }
     var onScrollChangeListener:ScrollChangeListener?=null
}

接口在这里

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<dp180){
                    layout_location.translationX=(-yScroll/dp180)*intervalLoation
                    layout_date.translationX=(-yScroll/dp180)*intervalDate
                    layout_location.translationY=(-yScroll/dp180)*40
                    layout_date.translationY=(-yScroll/dp180)*40
                    layout_temperature.translationX=200*(yScroll/dp180)
                    layout_temperature.translationY=(-yScroll/dp180)*80
                }

            }
        }

    }

相关文章

网友评论

      本文标题:仿系统原生天气毛坯版

      本文链接:https://www.haomeiwen.com/subject/ukjaqftx.html