<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[sinat_33150417的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/sinat_33150417</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; sinat_33150417]]></copyright><item><title><![CDATA[leetcode 417. 太平洋大西洋水流问题]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/107706541</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/107706541</guid><author>sinat_33150417</author><pubDate>Fri, 31 Jul 2020 09:45:05 +0800</pubDate><description><![CDATA[https://leetcode-cn.com/problems/pacific-atlantic-water-flow/

思路是从海洋开始逆流 如果可以逆流到 就标记为1 然后检查两个海洋都可以逆流到的区域

DFS


public List&lt;List&lt;Integer&gt;&gt; pacificAtlantic(int[][] matrix) {
        if (matrix.length == 0 || matrix[0].length == 0) {
           ]]></description><category></category></item><item><title><![CDATA[Android基础 -- 子线程可以修改UI吗？]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/105966376</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/105966376</guid><author>sinat_33150417</author><pubDate>Thu, 07 May 2020 11:14:12 +0800</pubDate><description><![CDATA[子线程可以修改UI吗？为什么会产生这样的问题，可能是因为在开发过程中遇到了


"Only the original thread that created a view hierarchy can touch its views."

这个异常信息，又或者是常用Handler将子线程中的数据更新到UI上，又或者是其他的一些原因，如果你思考到了为什么要在主线程中更新UI或者子线程中可以更新UI吗这...]]></description><category></category></item><item><title><![CDATA[Android Fragment退出 返回上一个Fragment与直接退出]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/105631300</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/105631300</guid><author>sinat_33150417</author><pubDate>Mon, 20 Apr 2020 11:40:31 +0800</pubDate><description><![CDATA[例如应用底部有两个导航按钮A与B，刚进入的时候显示为第一个AFragment，点击B切换到BFragment。

如果需求是在BFragment点击返回键回到AFragment，需要配置


app:defaultNavHost="true"

如果需求是在BFragment点击返回键直接退出，则配置为false


app:defaultNavHost="false"


...]]></description><category></category></item><item><title><![CDATA[Android基础 -- Jetpack组件的使用]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/105081170</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/105081170</guid><author>sinat_33150417</author><pubDate>Tue, 24 Mar 2020 21:06:58 +0800</pubDate><description><![CDATA[关于ViewModel、LiveData、DataBinding、LifeCycle、Paging和Room的使用，做了一期一个多小时的视频，不相关的基础代码都是在视频外写好，视频时间里会让小伙伴们以最快的速度了解Jetpack相关组件的使用，欢迎小伙伴们观看~

视频地址：https://www.bilibili.com/video/BV147411w7CJ/

源码地址：https://git...]]></description><category></category></item><item><title><![CDATA[ViewModelProviders is deprecated]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/104323897</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/104323897</guid><author>sinat_33150417</author><pubDate>Sat, 15 Feb 2020 10:18:22 +0800</pubDate><description><![CDATA[原有的创建ViewModel的方法：


viewModel = ViewModelProviders.of(this).get(ViewModel.class);

提示ViewModelProviders过时



改为：


viewModel = new ViewModelProvider(this).get(ViewModel.class);


...]]></description><category></category></item><item><title><![CDATA[Android基础 -- 自定义View中构造代码块的使用]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/103392047</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/103392047</guid><author>sinat_33150417</author><pubDate>Thu, 05 Dec 2019 00:47:10 +0800</pubDate><description><![CDATA[自定义View想必大家都不陌生，会想自定义View的第一步，就是给它添加不同的构造方法，然后这里可能会有不同的写法，下面是两种常见的写法。

第一种是在每个构造方法里都加上初始化方法


public CustomView(Context context) {
        super(context);
        init();
    }

    public CustomView(...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- Retrofit源码结构]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/103314412</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/103314412</guid><author>sinat_33150417</author><pubDate>Fri, 29 Nov 2019 18:49:17 +0800</pubDate><description><![CDATA[Retrofit的源码结构是很简单的，注意这里说的是源码结构，不是源码细节，源码细节十分复杂，本篇文章在于理清Retrofit的源码结构及分享一种看源码的方法。



一、Retrofit的使用

使用这里使用官方文档的例子

1.新建一个存放请求方法的接口


public interface GitHubService {
    @GET("users/{user}/repos")
   ...]]></description><category></category></item><item><title><![CDATA[Android基础 -- 贝塞尔曲线]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102978286</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102978286</guid><author>sinat_33150417</author><pubDate>Fri, 08 Nov 2019 22:30:34 +0800</pubDate><description><![CDATA[一、简介

关于贝塞尔曲线（百度百科）的定义，很多博客都有着详细的介绍，本篇博客来关注具体的实现过程。

首先来看2阶、3阶贝塞尔曲线的效果图



接下来，看具体的实现过程。

项目地址：https://github.com/zhangtiansimple/AndroidBasis



二、二阶贝塞尔曲线

要想画出二阶贝塞尔曲线，首先需要定义两个坐标点和一个控制点，然后是画笔路径等。


...]]></description><category></category></item><item><title><![CDATA[Android开源项目 -- 展开收起TextView]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102823781</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102823781</guid><author>sinat_33150417</author><pubDate>Sun, 03 Nov 2019 22:04:19 +0800</pubDate><description><![CDATA[一、项目简介

项目地址：https://github.com/zhangtiansimple/FoldTextView

效果图： 



二、技术选型

本项目采用LinearLayout与TextView实现，根据开发者设置的最大行数，计算高度然后设置给LinearLayout，从而实现文本折叠的功能。



三、具体实现

1.定义子View的布局

即文字的展示TextView与下...]]></description><category></category></item><item><title><![CDATA[Android开源项目 -- 轮播Banner]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102822988</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102822988</guid><author>sinat_33150417</author><pubDate>Fri, 01 Nov 2019 22:37:14 +0800</pubDate><description><![CDATA[一、项目简介

项目地址：https://github.com/zhangtiansimple/CarouselBanner

效果图：



二、技术选型

本开源项目采用RecycleView实现，由于一直轮播的关系，需要不断的加载下一页，借用RecyclerView的缓存机制，可以很好的实现内存的管理。



三、具体实现

1.基本布局

最外层采用FrameLayout作为根布局，然...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- 知乎Matisse源码解析（四）]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102702411</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102702411</guid><author>sinat_33150417</author><pubDate>Wed, 30 Oct 2019 22:32:24 +0800</pubDate><description><![CDATA[本篇博客一起来看Matisse的数据加载机制。

一、AlbumLoader

Matisse采用Loader机制进行加载，先来看AlbumLoader。AlbumLoader集成自CursorLoader，作为资源加载器，加载好资源之后，通过AlbumCollection实现的LoaderManager.LoaderCallbacks接口，将包含数据的Cursor回调给外部调用的MatissAc...]]></description><category></category></item><item><title><![CDATA[LeetCode分类整理及解题记录]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102566740</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102566740</guid><author>sinat_33150417</author><pubDate>Thu, 24 Oct 2019 22:40:08 +0800</pubDate><description><![CDATA[Github项目地址：

https://github.com/zhangtiansimple/Leetcode

如果有那么一点点帮助到了小伙伴，还请给予个小小的star鼓励～
]]></description><category></category></item><item><title><![CDATA[Android进阶 -- 知乎Matisse源码解析（三）]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102679668</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102679668</guid><author>sinat_33150417</author><pubDate>Thu, 24 Oct 2019 22:18:46 +0800</pubDate><description><![CDATA[这篇博客来重点关注Matisse里的自定义View，在MatisseActivity里，看到的逻辑十分流畅，是因为将细节部分都已经封装到了这些不同的组件中了，接下来一起看看这些组件的具体实现。

一、AlbumSpinner

AlbumSpinner用来在MatisseActivity里实现不同媒体文件夹的选取，使用ListPopupWindow作为UI显示，使用AlbumsAdapter返回的...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- 知乎Matisse源码解析（二）]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102667182</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102667182</guid><author>sinat_33150417</author><pubDate>Wed, 23 Oct 2019 23:17:28 +0800</pubDate><description><![CDATA[上一篇分析了启动MatissActivity之前的逻辑，接下来看MatissActivity。



一、实现接口


public class MatisseActivity extends AppCompatActivity implements
        AlbumCollection.AlbumCallbacks, AdapterView.OnItemSelectedListene...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- 知乎Matisse源码解析（一）]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102664404</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102664404</guid><author>sinat_33150417</author><pubDate>Mon, 21 Oct 2019 22:53:18 +0800</pubDate><description><![CDATA[Matisse做了这样一件事情，在需要选择图片视频的时候，调用


Matisse.from(MainActivity.this)
        .choose(MimeType.allOf())
        .countable(true)
        .maxSelectable(9)
        .addFilter(new GifSizeFilter(320, 320, 5 ...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- 屏幕刷新机制]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102562661</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102562661</guid><author>sinat_33150417</author><pubDate>Wed, 16 Oct 2019 22:04:51 +0800</pubDate><description><![CDATA[关于屏幕卡顿，从表象来讲，是因为主线程有耗时操作，导致屏幕绘制掉帧，屏幕每16毫秒会刷新一次，也就是每秒刷新60次，人眼能感觉到的卡顿的帧率是每秒24帧。所以解决卡顿的一般处理方法就是将耗时操作放在子线程、减少View层级、多使用include merge viewstub标签等，来保障屏幕绘制的流畅。

不过再往深里看，会有这样一些问题：卡顿的底层原因是什么？如何理解16毫米刷新一次？假如界面没...]]></description><category></category></item><item><title><![CDATA[Android基础 -- SurfaceView]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102520161</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102520161</guid><author>sinat_33150417</author><pubDate>Sat, 12 Oct 2019 23:14:22 +0800</pubDate><description><![CDATA[一、什么是SurfaceView
普通的View是通过Android系统发出的VSYNC信息来进行屏幕的绘制，但是在一些需要频繁刷新的场景，如直播、游戏等，如果执行了很多操作，就会导致绘制间隔超时，也就是用户感知的卡顿，SurfaceView就是为了应对这样的场景而诞生的。SurfaceView继承自View，拥有独立的绘制表面，即它不与其父View共享同一个绘制表面，可以单独在一个线程进行绘制，...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- 避免创建不必要的对象]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/102511546</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/102511546</guid><author>sinat_33150417</author><pubDate>Fri, 11 Oct 2019 22:32:21 +0800</pubDate><description><![CDATA[在内存调优的过程中，如何避免创建不必要的对象，一直是很重要的一个方面，下面来一起看看常用的避免创建对象的方法。

1.字符串的拼接


public static String buildString(String[] values) {
	String res = “”;
	for (String value : values) {
		res += values;
	}
	return res...]]></description><category></category></item><item><title><![CDATA[Android常用工具 -- 颜色透明度]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/101205965</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/101205965</guid><author>sinat_33150417</author><pubDate>Sat, 28 Sep 2019 22:58:58 +0800</pubDate><description><![CDATA[在开发中常常会遇到这种情况，设计师给出的色值有一个透明度，这个时候就需要我们自己添加在色值的前两位，下面是常用透明度对照表


&lt;!--透明度百分比 : 8位颜色值前两位--&gt;
    &lt;!--100% : FF--&gt;
    &lt;!--95% : F2--&gt;
    &lt;!--90% : E6--&gt;
    &lt;!--85% : D9--&gt;
...]]></description><category></category></item><item><title><![CDATA[Android进阶 -- postDelay原理解析]]></title><link>https://blog.youkuaiyun.com/sinat_33150417/article/details/101291065</link><guid>https://blog.youkuaiyun.com/sinat_33150417/article/details/101291065</guid><author>sinat_33150417</author><pubDate>Sat, 28 Sep 2019 00:23:22 +0800</pubDate><description><![CDATA[在日常开发中，需要延时任务的时候，往往会用到handler.postDelay()的方法，那么一起来看看它的内部实现原理吧。


//Handler.java
public final boolean postDelayed(Runnable r, long delayMillis)
    {
        return sendMessageDelayed(getPostMessage(r)...]]></description><category></category></item></channel></rss>