前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一线开发者本周复盘2

一线开发者本周复盘2

作者头像
AndroidTraveler
发布2019-04-25 15:16:55
3700
发布2019-04-25 15:16:55
举报
文章被收录于专栏:AndroidTraveler

时间:2019.03.25~2019.03.29

需求

要求根据文本内容对背景图片自动做裁剪?

什么意思呢?

就是给你一张图,当文本显示两行的时候,全部显示。

如果只显示一行,那么就显示上半部分。

为了便于理解,这边自己用 sketch 做了一张背景图。

这里要求当你文本显示一行,只显示上面第一个色块,当文本为两行时,显示两个色块。

分析

既然需求出来了,那么我们就开始进行分析。

这里最重要的其实是拆分思维。这个需求其实可以拆为两个小需求。

  1. 给定一张图片,你能够进行裁剪操作。
  2. 你能够判断当前文本显示的行数。

如果你能够解决这两个小需求,那么这个需求也就迎刃而解了。

图片裁剪

如何进行图片裁剪呢?

其实很简单,只要在 drawable 下面创建一个 xml 文件即可。

模板代码如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?><clip xmlns:android="http://schemas.android.com/apk/res/android"    android:clipOrientation="vertical"    android:drawable="@mipmap/img_bg"    android:gravity="top"/>

参数解析:

clipOrientation 你可以认为是裁剪的对齐方向,这里设置为 vertical,说明我们想保留的是竖直方向。而我们上面的需求确实是这样的,两个色块,在竖直方向为上和下。

drawable 就是要操作的图片了。

gravity 你可以认为是裁剪要保留具体哪部分。比如这里竖直方向有上和下,那么你是要保留上面还是下面呢?

说起来有点难以理解,我们通过下面 4 种情况的图片再结合上面说明你就理解了。

看这个图两个字段两两组合的情况相信你应该能够理解了。

准备好了 xml,还没有完哦~

我们这边在界面 xml 设置一个 ImageView 来演示,ImageView 布局如下:

代码语言:javascript
复制
<ImageView    android:id="@+id/clip_bg"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/clip_bg" />

这里我们指定了 src 就是我们刚刚在 drawable 下面创建的 clip_bg.xml。

这个时候如果你激动的直接运行,会发现啥都没有?

其实也很好理解,因为你要裁剪图片,那么你是要裁一半还是要裁 25%,你至少要告诉我,不然我怎么裁,所以接下来我们要指定裁的比例。

在 MainActivity.java 里面,我们找到对应 ImageView 并设置如下:

代码语言:javascript
复制
ImageView imageView = findViewById(R.id.clip_bg);ClipDrawable clipDrawable = (ClipDrawable) imageView.getDrawable();clipDrawable.setLevel(50 * 100);

可以看到也很简单,不过有个比较好奇的,就是 setLevel 里面的数值,我们点进去源码,可以看到这个参数的解释:

代码语言:javascript
复制
@param level The new level, from 0 (minimum) to 10000 (maximum).

可以看到这个值是 0~10000,因此我们这里设置 5000,其实就是要裁剪一半的意思了。为了方便表示裁剪比例,所以用 50 * 100,这里的 50 就是裁剪 50% 啦。

这个时候你运行就没问题啦~

判断文本显示行数

这个方法多种多样,我们简单采取下面方法:

代码语言:javascript
复制
tv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {    @Override    public boolean onPreDraw() {        //tv.getLineCount()                tv.getViewTreeObserver().removeOnPreDrawListener(this);         return false;    }});

解决问题

既然上面两个问题都可以得到解决,那么问题也就可以解决了。

我们布局如下:

代码语言:javascript
复制
<?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="match_parent"    android:orientation="vertical"    >
    <LinearLayout        android:id="@+id/linear"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical"        android:background="@drawable/clip_bg"        >
        <TextView            android:id="@+id/tv"            android:layout_width="20dp"            android:layout_height="wrap_content"            android:maxLines="2"            android:ellipsize="end"            />
    </LinearLayout>
</LinearLayout>

主界面代码如下:

代码语言:javascript
复制
package com.nesger.androidsample;
import android.graphics.drawable.ClipDrawable;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.ViewTreeObserver;import android.widget.LinearLayout;import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                final TextView tv = findViewById(R.id.tv);        LinearLayout linearLayout = findViewById(R.id.linear);        final ClipDrawable clipDrawable = (ClipDrawable) linearLayout.getBackground();        tv.setText("1");        changeBg(tv, clipDrawable);        tv.postDelayed(new Runnable() {            @Override            public void run() {                tv.setText(">1 is must,so just test");                changeBg(tv, clipDrawable);            }        }, 5000);    }
    private void changeBg(final TextView tv, final ClipDrawable clipDrawable) {        tv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {            @Override            public boolean onPreDraw() {                //tv.getLineCount()                tv.getViewTreeObserver().removeOnPreDrawListener(this);                if (tv.getLineCount() == 1) {                    clipDrawable.setLevel(50 * 100);                } else {                    clipDrawable.setLevel(100 * 100);                }                return false;            }        });    }}

这里只是简单的演示下效果而已。

源码点击阅读原文或者拷贝下面链接浏览器打开:?

https://github.com/nesger/AndroidSample

温馨提示

细心的小伙伴会发现我们在获取 ClipDrawable 的时候,对于 ImageView,使用的是

代码语言:javascript
复制
ClipDrawable clipDrawable = (ClipDrawable) imageView.getDrawable();

而对于 LinearLayout 使用的是

代码语言:javascript
复制
ClipDrawable clipDrawable = (ClipDrawable) linearLayout.getBackground();

因此在使用的时候,要测试一下,避免出现调用 API 错误导致空指针问题。

总结

拆分思维很重要。

一个需求,如果可以拆分成小的需求,就进行需求拆分。

当不能再拆分的时候,解决起来会比直接解决大需求要容易和快的多。

当所有小需求都解决了,大需求自然迎刃而解。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 安卓小煜 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档