Android 天气APP(九)细节优化、必应每日一图

  • 颜色波浪TextView

*/

public class LoadingTextView extends AppCompatTextView {

private LinearGradient mLinearGradient;

private Matrix mGradientMatrix;

private Paint mPaint;

private int mViewWidth = 0;

private int mTranslate = 0;

private boolean mAnimating = true;

public LoadingTextView(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

if (mViewWidth == 0) {

mViewWidth = getMeasuredWidth();

if (mViewWidth > 0) {

mPaint = getPaint();

mLinearGradient = new LinearGradient(-mViewWidth, 0, 0, 0,

new int[]{0x33ffffff, 0xff3286ED, 0x33ffffff},

new float[]{0, 0.5f, 1}, Shader.TileMode.CLAMP);

mPaint.setShader(mLinearGradient);

mGradientMatrix = new Matrix();

}

}

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (mAnimating && mGradientMatrix != null) {

mTranslate += mViewWidth / 10;

if (mTranslate > 2 * mViewWidth) {

mTranslate = -mViewWidth;

}

mGradientMatrix.setTranslate(mTranslate, 0);

mLinearGradient.setLocalMatrix(mGradientMatrix);

postInvalidateDelayed(50);

}

}

}

LoadingView.java

package com.llw.mvplibrary.view;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.util.AttributeSet;

import androidx.annotation.Nullable;

import com.llw.mvplibrary.R;

import java.lang.ref.SoftReference;

/**

  • 加载框

*/

public class LoadingView extends androidx.appcompat.widget.AppCompatImageView {

private int mCenterRotateX;//图片旋转点x

private int mCenterRotateY;//图片旋转点y

private LoadingRunnable mRunnable;

public LoadingView(Context context) {

this(context, null);

}

public LoadingView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init() {

setScaleType(ScaleType.MATRIX);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.loading);

setImageBitmap(bitmap);

mCenterRotateX = bitmap.getWidth() / 2;

mCenterRotateY = bitmap.getHeight() / 2;

}

/**

  • onDraw()之前调用

*/

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

if (mRunnable==null){

mRunnable=new LoadingRunnable(this);

}

if (!mRunnable.isLoading){

mRunnable.start();

}

}

/**

  • view销毁时调用

*/

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

if (mRunnable!=null){

mRunnable.stop();

}

mRunnable=null;

}

class LoadingRunnable implements Runnable {

private boolean isLoading;

private Matrix mMatrix;

private SoftReference mLoadingViewSoftReference;

private float mDegrees = 0f;

public LoadingRunnable(LoadingView loadingView) {

mLoadingViewSoftReference = new SoftReference(loadingView);

mMatrix = new Matrix();

}

@Override

public void run() {

if (mLoadingViewSoftReference.get().mRunnable != null && mMatrix != null) {

mDegrees += 30f;

mMatrix.setRotate(mDegrees, mCenterRotateX, mCenterRotateY);

mLoadingViewSoftReference.get().setImageMatrix(mMatrix);

if (mDegrees==360){

mDegrees=0f;

}

if (isLoading) {

mLoadingViewSoftReference.get().postDelayed(mLoadingViewSoftReference.get().mRunnable, 100);

}

}

}

public void stop() {

isLoading = false;

}

public void start() {

isLoading = true;

if (mLoadingViewSoftReference.get().mRunnable != null && mMatrix != null) {

mLoadingViewSoftReference.get().postDelayed(mLoadingViewSoftReference.get().mRunnable, 100);

}

}

}

}

在模块的res文件夹下创建一个新的layout文件夹用处存放布局文件,然后创建一个弹窗的布局文件dialog_loading.xml

在这里插入图片描述

代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

android:id=“@+id/layout_loading”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_gravity=“center”

android:background=“@drawable/ic_loading_bg”

android:gravity=“center”

android:orientation=“vertical”

android:padding=“16dp”>

<com.llw.mvplibrary.view.LoadingView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content” />

<com.llw.mvplibrary.view.LoadingTextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginTop=“8dp”

android:text=“加载中…”

android:textColor=“#fff”

android:textSize=“16sp” />

当然弹窗的出现和消失也是要给动画的。

在模块的styles.xml文件中增加。

在这里插入图片描述

接下来就是使用了,考虑到可能有多个地方要使用这个,所以将使用方法封装到底层的BaseActivity中,

private Dialog mDialog;//加载弹窗

//弹窗出现

public void showLoadingDialog(){

if (mDialog == null) {

mDialog = new Dialog(context, R.style.loading_dialog);

}

mDialog.setContentView(R.layout.dialog_loading);

mDialog.setCancelable(false);

mDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

mDialog.show();

}

//弹窗消失

public void dismissLoadingDialog(){

if (mDialog != null) {

mDialog.dismiss();

}

mDialog = null;

}

同理,在BaseFragment中也放入,使用过程中只要你的Activity继承了BaseActivity或者MvpActivity都可以调用弹窗的出现和消失方法。

接下来在MainActivity中使用。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

接下来进行必应每日一图的接口访问。

访问地址:

https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1

访问之后:

在这里插入图片描述

用这串地址返回的数据生成一个实体Bean。

在项目的bean包下创建一个BiYingImgResponse.java

在这里插入图片描述

代码如下:

package com.llw.goodweather.bean;

import java.util.List;

public class BiYingImgResponse {

/**

  • images : [{“startdate”:“20200406”,“fullstartdate”:“202004061600”,“enddate”:“20200407”,“url”:“/th?id=OHR.PinkMoon_ZH-CN9026483067_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp”,“urlbase”:“/th?id=OHR.PinkMoon_ZH-CN9026483067”,“copyright”:“四月的满月从圣迈克尔山上升起,英国康沃尔 (© Simon Maycock/Alamy Live News)”,“copyrightlink”:“https://www.bing.com/search?q=%E5%9C%A3%E7%B1%B3%E6%AD%87%E5%B0%94%E5%B1%B1&form=hpcapt&mkt=zh-cn”,“title”:“”,“quiz”:“/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20200406_PinkMoon%22&FORM=HPQUIZ”,“wp”:true,“hsh”:“571d8c115ed49dad56d5f1e678ddeeb1”,“drk”:1,“top”:1,“bot”:1,“hs”:[]}]

  • tooltips : {“loading”:“正在加载…”,“previous”:“上一个图像”,“next”:“下一个图像”,“walle”:“此图片不能下载用作壁纸。”,“walls”:“下载今日美图。仅限用作桌面壁纸。”}

*/

private TooltipsBean tooltips;

private List images;

public TooltipsBean getTooltips() {

return tooltips;

}

public void setTooltips(TooltipsBean tooltips) {

this.tooltips = tooltips;

}

public List getImages() {

return images;

}

public void setImages(List images) {

this.images = images;

}

public static class TooltipsBean {

/**

  • loading : 正在加载…

  • previous : 上一个图像

  • next : 下一个图像

  • walle : 此图片不能下载用作壁纸。

  • walls : 下载今日美图。仅限用作桌面壁纸。

*/

private String loading;

private String previous;

private String next;

private String walle;

private String walls;

public String getLoading() {

return loading;

}

public void setLoading(String loading) {

this.loading = loading;

}

public String getPrevious() {

return previous;

}

public void setPrevious(String previous) {

this.previous = previous;

}

public String getNext() {

return next;

}

public void setNext(String next) {

this.next = next;

}

public String getWalle() {

return walle;

}

public void setWalle(String walle) {

this.walle = walle;

}

public String getWalls() {

return walls;

}

public void setWalls(String walls) {

this.walls = walls;

}

}

public static class ImagesBean {

/**

  • startdate : 20200406

  • fullstartdate : 202004061600

  • enddate : 20200407

  • url : /th?id=OHR.PinkMoon_ZH-CN9026483067_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp

  • urlbase : /th?id=OHR.PinkMoon_ZH-CN9026483067

  • copyright : 四月的满月从圣迈克尔山上升起,英国康沃尔 (© Simon Maycock/Alamy Live News)

  • copyrightlink : https://www.bing.com/search?q=%E5%9C%A3%E7%B1%B3%E6%AD%87%E5%B0%94%E5%B1%B1&form=hpcapt&mkt=zh-cn

  • title :

  • quiz : /search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20200406_PinkMoon%22&FORM=HPQUIZ

  • wp : true

  • hsh : 571d8c115ed49dad56d5f1e678ddeeb1

  • drk : 1

  • top : 1

  • bot : 1

  • hs : []

*/

private String startdate;

private String fullstartdate;

private String enddate;

private String url;

private String urlbase;

private String copyright;

private String copyrightlink;

private String title;

private String quiz;

private boolean wp;

private String hsh;

private int drk;

private int top;

private int bot;

private List<?> hs;

public String getStartdate() {

return startdate;

}

public void setStartdate(String startdate) {

this.startdate = startdate;

}

public String getFullstartdate() {

return fullstartdate;

}

public void setFullstartdate(String fullstartdate) {

this.fullstartdate = fullstartdate;

}

public String getEnddate() {

return enddate;

}

public void setEnddate(String enddate) {

this.enddate = enddate;

}

public String getUrl() {

return url;

}

public void setUrl(String url) {

this.url = url;

}

public String getUrlbase() {

return urlbase;

}

public void setUrlbase(String urlbase) {

this.urlbase = urlbase;

}

public String getCopyright() {

return copyright;

}

public void setCopyright(String copyright) {

this.copyright = copyright;

}

public String getCopyrightlink() {

return copyrightlink;

}

public void setCopyrightlink(String copyrightlink) {

this.copyrightlink = copyrightlink;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public String getQuiz() {

return quiz;

}

public void setQuiz(String quiz) {

this.quiz = quiz;

}

public boolean isWp() {

return wp;

}

public void setWp(boolean wp) {

this.wp = wp;

}

public String getHsh() {

return hsh;

}

public void setHsh(String hsh) {

this.hsh = hsh;

}

public int getDrk() {

return drk;

}

public void setDrk(int drk) {

this.drk = drk;

}

public int getTop() {

return top;

}

public void setTop(int top) {

this.top = top;

}

public int getBot() {

return bot;

}

public void setBot(int bot) {

this.bot = bot;

}

public List<?> getHs() {

return hs;

}

public void setHs(List<?> hs) {

this.hs = hs;

}

}

}

这个地方写API的时候就要注意了,因为必应的访问地址和和风的访问地址不一样,所以这里要用分支来做,首先修改ServiceGenerator

修改后的代码:

package com.llw.mvplibrary.net;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;

import okhttp3.logging.HttpLoggingInterceptor;

import retrofit2.Retrofit;

import retrofit2.converter.gson.GsonConverterFactory;

public class ServiceGenerator {

//https://free-api.heweather.net/s6/weather/now?key=3086e91d66c04ce588a7f538f917c7f4&location=深圳

//将上方的API接口地址进行拆分得到不变的一部分,实际开发中可以将这一部分作为服务器的ip访问地址

public static String BASE_URL = null;//地址

private static String urlType(int type){

switch (type){

case 0://和风天气

BASE_URL = “https://free-api.heweather.net”;

break;

case 1://必应每日一图

BASE_URL = “https://cn.bing.com”;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值