转载请注明出处:http://blog.csdn.net/binbinqq86/article/details/72731048
最近在研究图表的绘制,帮朋友解决一个天气软件的温度趋势问题,他之前用的是helloCharts来实现的(最终demo效果),于是我就按照他的思路继续研究下去了,最终发现了一个更为简单的方法,就抛弃了helloCharts,最终自己整理了一下做出来一个仿小米天气的15天趋势预报效果,看图:
偷了点懒,没有做到完全一样,这里只是抛砖引玉,提供一个思路~其实就是两个自定义view,说下主要实现思路:先抛去中间的图表,15天的预报,每天都是一个相同的view,这里我们用一个自定义viewgroup,把这些view一起加入进来,每个view的宽度是固定的,这样就有了整个viewgroup的宽度,而高度采用自适应,再来看图表,我们的图表也是一个自定义view(专门用来负责绘制温度图表),这里把它加到前面的viewgroup里面去,这样所有相关的view就加进来了,在layout的时候再去分别设定其具体位置,最后在最外层套一个HorizontalScrollView,至此,就滑动起来了,当然也可以自己去实现滑动,这里就偷懒啦,用系统控件来代替。简单吧?
下面看相关代码:
package com.example.tb.xiaomiweather;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by tb on 2017/5/13.
* 未来若干天天气滑动控件
*/
public class ScrollFutureDaysWeatherView extends ViewGroup{
private static final String TAG = "ScrollFutureDaysWeatherView";
/**
* 未来若干天天气View的集合(每个item都是一样的)
*/
private List<View> contents=new ArrayList<>();
/**
* 未来若干天天气温度的图表
*/
private FutureDaysChart sevenDaysChart;
/**
* 未来具体的天数(包含昨天一个)
*/
public static final int days=16;
/**
* 每个item的宽度
*/
private int futureDayItemWidth;
/**
* 温度图表的高度
*/
private int futureDayChartHeight;
/**
* 未来若干天天气控件总宽度(viewgroup的宽度)
*/
private int futureDayTotalWidth;
/**
* 具体的每个item的宽度(单位:dp)
*/
public static final int ITEM_WIDTH=80;
public ScrollFutureDaysWeatherView(Context context) {
this(context,null);
}
public ScrollFutureDaysWeatherView(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public ScrollFutureDaysWeatherView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ScrollFutureDaysWeatherView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context){
futureDayItemWidth= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,ITEM_WIDTH,context.getResources().getDisplayMetrics());
futureDayChartHeight=(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,FutureDaysChart.CHART_HEIGHT,context.getResources().getDisplayMetrics());
futureDayTotalWidth=futureDayItemWidth*days;
for (int i = 0; i < days; i++) {
View view=LayoutInflater.from(context).inflate(R.layout.item_future_days_weather, null, false);
view.findViewById(R.id.view).getLayoutParams().height=futureDayChartHeight;
contents.add(view);
addView(view,new LayoutParams(futureDayItemWidth,LayoutParams.WRAP_CONTENT));
}
sevenDaysChart=new FutureDaysChart(context);
addView(sevenDaysChart,new LayoutParams(futureDayTotalWidth,LayoutParams.WRAP_CONTENT));
}
public List<View> getAllViews(){
return contents;
}
public FutureDaysChart getSevenDaysChart(){
return sevenDaysChart;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int totalHeight=0;
for (int i = 0; i < getChildCount(); i++) {
View childView = getChildAt(i);
if(childView.getVisibility()!=View.GONE){
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
totalHeight+=childView.getMeasuredHeight();
}
}
//为ViewGroup设置宽高
setMeasuredDimension(futureDayTotalWidth,totalHeight);
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
int left=0;
for (int j = 0; j < getChildCount()-1; j++) {
View child=getChildAt(j);
if(child.getVisibility()!=View.GONE){
child.layout(left,0,left+child.getMeasuredWidth(),child.getMeasuredHeight());
left+=futureDayItemWidth;
}
}
View emptyView=contents.get(0).findViewById(R.id.view);
int top=emptyView.getTop();
View last=getChildAt(getChildCount()-1);
last.layout(0,top,getMeasuredWidth(),top+futureDayChartHeight);
}
}
上面就是自定义的viewgroup,包含了所有需要的子控件,里面的每天天气的布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/tv_week"