GcsSloop / AndroidNote

安卓学习笔记
http://www.gcssloop.com/#blog
9.17k stars 2.14k forks source link

这是我看到最好的自定义教程,没有之一,非常感谢 #77

Open 819715035 opened 7 years ago

819715035 commented 7 years ago

这是我看到最好的自定义教程,没有之一,非常感谢

musicode commented 6 years ago

@GcsSloop 我想问一个问题,如果希望组合几个 TextView 形成一个新的 view,这种能用自定义 view 么?

GcsSloop commented 6 years ago

可以的,用自定义 ViewGroup。

musicode commented 6 years ago

自定义 viewgroup,配合使用 res/layout/xxx.xml(在这里写布局,比如用 LinearLayout 套两个 TextView) 是么?

zhangXiaolizi commented 6 years ago

@musicode 是的,自定义View的时候可以引入布局的。

GcsSloop commented 6 years ago

可以的,然后在自定义的Group中填充这个布局就行了。例如:

public class TitleBar extends ConstraintLayout  {
    private View mGroup;

    public TitleBar(Context context) {
        this(context, null);
    }

    public TitleBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViews(context);
    }

    private void initViews(Context context) {
        // 填充布局
        mGroup = LayoutInflater.from(context).inflate(R.layout.item_titlebar, this);
    }
}
musicode commented 6 years ago

谢谢

musicode commented 6 years ago

@GcsSloop 自定义 view 这个系列似乎缺少关于 ViewGroup 的

GcsSloop commented 6 years ago

因为这个系列目前只更新了大约一半的内容,因为刚工作,时间不足暂时停更了一年,最近可能会恢复更新。

musicode commented 6 years ago

你才刚工作啊,厉害厉害!

musicode commented 6 years ago

请教一个问题,通常我们会在 res/values/dimens.xml 定义一些尺寸,比如间距之类的,但有些尺寸,其实是运行时才知道的,比如我们知道左右间距是 10dp,但中间多大,则需要取屏幕宽度减去左右间距(我理解只需要初始化的时候算一次存入 dimens 即可),此时,如果希望在模板里设置一个 maxWidth 的自定义属性,是否有可能实现呢?

app:maxWidth="动态算出的宽度"
GcsSloop commented 6 years ago

我可能没有理解你说的这个内容的应用场景。 如果是自己自定义View,测量阶段就可以拿到屏幕宽高、最大可用宽度,padding 等数值,根据这些数值自然就可以计算出所需的尺寸信息,然后直接通过相关的方法应用该宽度就可以了。没有必要计算出来后存储起来再拿来使用。 如果是官方控件的属性,定义为 wrap_content ,设置了 margin 后,它的最大宽度自然就被限制了。 如果是第三方控件,定义为 wrap_content ,设置了 margin 后,它的显示的最大宽度超出了可以用区域,说明这个控件本身就存在问题,没有按照官方的标准来执行,是控件自身的问题,建议自己进行修改调整,或者换一个其他的控件来代替,

musicode commented 6 years ago

大概理解了你的意思,其实差不多,我希望的是自定义 view 能解耦,举个微信聊天界面的例子 image 1 是间距,2 是头像的宽度,3又是一个间距,右边的气泡仍然是这个结构

当我开发一个内容区的 view 时,这个 view 的最大宽度如下

最大宽度 = 屏幕宽度 - 2 x (代号1 + 代号2 + 代号3)

这个逻辑确实可以在 view 内部去写,但是就耦合了外部的布局逻辑,我是希望能解耦的

GcsSloop commented 6 years ago

也就是说内容区域最大如红框所示的意思吧。 一般来说,1、2、3 都是设置的具体 dp 数值,那么 1 + 2 + 3 在最开始就是已知的,那么设置具体内容区域(蓝框所示)的时候直接设置 marginRight 的数值为 1 + 2 +3 的 dp 数值就可以了。

musicode commented 6 years ago

设置了 marginRight 之后,自定义 view 取 最大可用宽度 就能取到红框的宽度了吧

GcsSloop commented 6 years ago

如果上层View是按照规范来的,是这样的。

musicode commented 6 years ago

好的,感谢指点~

musicode commented 6 years ago

请教一个关于获取宽高的问题,布局如下:

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/gridView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:overScrollMode="never"/>

</FrameLayout>

我的需求是获取 frame layout 的宽高,从而计算 grid 每个格子的大小,但是按上面这种布局,frameLayout.measuredWidthframeLayout.measuredHeight 都是 0,令人不解的是,我设置的背景色却能显示出来。

如果我把布局改成下面这样,就能正常获取 frame layout 的尺寸

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

    <!-- 在这加了一个 match_parent 的空视图 ->
    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/gridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:overScrollMode="never"/>

</FrameLayout>

我的问题如下:

  1. 为啥 frame layout 自己设置了 match_parent 却无法获取尺寸呢?
  2. 获取 frame layout 的尺寸是通过 measuredWidthmeasuredHeight 吗?或者有啥更好的方法或流程吗?
  3. 我不是很想加一个空 View 来辅助计算 frame layout 的尺寸,是否有可能去掉它也能获取尺寸呢?

感谢