“e8415271ee0e42ecf51c2c3705e891e183748b72”上不存在“...reference/git@gitcode.net:openharmony/docs.git”
提交 68f36e08 编写于 作者: D dallascao

1

上级
---
name: Bug report
about: Something is crashing or not working as intended
labels: bug
---
如果你有能力,请考虑提出 pull 项要求。请注意,2.0.0 之前的版本不再受支持。
库版本:
2.X.X
受影响的设备:
搭载 Android9.0 的谷歌 Pixel3XL
描述这个错误:
对错误是什么有一个清晰的描述。
复制:
1.
2.
3.
预期行为:
清楚地描述你预期会发生的事情。
---
name: Feature request
about: Suggest an idea for this project
labels: improvement
---
如果你有能力,请考虑提出 pull 项要求。请注意,2.0.0 之前的版本不再受支持。
这适用于什么模块?
核心?输入?文件?颜色?
描述你希望发生的事情:
如果你希望实现的特性或行为,请提供清晰的描述。
描述一下你考虑过的替代方案:
清楚地描述你考虑过的任何替代解决方案。
---
name: Bug report
about: Something is crashing or not working as intended
labels: bug
---
*Please consider making a Pull Request if you are capable of doing so. Note that versions before 2.0.0 are no longer supported.*
**Library Version:**
2.x.x
**Affected Device(s):**
Google Pixel 3 XL with Android 9.0
**Describe the Bug:**
A clear description of what is the bug is.
**To Reproduce:**
1.
2.
3.
**Expected Behavior:**
A clear description of what you expected to happen.
---
name: Feature request
about: Suggest an idea for this project
labels: improvement
---
*Please consider making a Pull Request if you are capable of doing so. Note that versions before 2.0.0 are no longer supported.*
**What module does this apply to?**
Core? Input? Files? Color?
**Description what you'd like to happen:**
A clear description if the feature or behavior you'd like implemented.
**Describe alternatives you've considered:**
A clear description of any alternative solutions you've considered.
### Guidelines
1. You must run the `spotlessApply` task before commiting, either through Android Studio or with `./gradlew spotlessApply`.
2. A PR should be focused and contained. If you are changing multiple unrelated things, they should be in separate PRs.
3. A PR should fix a bug or solve a problem - something that only you would use is not necessarily something that should be published.
4. Give your PR a detailed title and description - look over your code one last time before actually creating the PR. Give it a self-review.
**If you do not follow the guidelines, your PR will be rejected.**
### 指导方针
1. 在提交之前,你必须运行 `spotlessApply` 任务,可以通过 Android Studio,也可以使用 `./gradlew spotlessApply`
2. 公关应该是集中和控制的。如果你正在更改多个不相关的事情,它们应该在单独的 PRS 中。
3. 公关人员应该修复一个 bug 或解决一个问题--只有你才会使用的东西不一定是应该发布的东西。
4. 给你的 PR 一个详细的标题和描述-在实际创建 PR 之前,最后一次查看你的代码。自我检讨一下。
如果你不遵守准则,你的公关将被拒绝。
Attribution-NonCommercial-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-ShareAlike 4.0 International Public License
("Public License"). To the extent this Public License may be
interpreted as a contract, You are granted the Licensed Rights in
consideration of Your acceptance of these terms and conditions, and the
Licensor grants You such rights in consideration of benefits the
Licensor receives from making the Licensed Material available under
these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. BY-NC-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative
Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name
of a Creative Commons Public License. The License Elements of this
Public License are Attribution, NonCommercial, and ShareAlike.
h. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
i. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of
this Public License, the exchange of the Licensed Material for
other material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is
no payment of monetary compensation in connection with the
exchange.
l. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
m. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
n. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part, for NonCommercial purposes only; and
b. produce, reproduce, and Share Adapted Material for
NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. Additional offer from the Licensor -- Adapted Material.
Every recipient of Adapted Material from You
automatically receives an offer from the Licensor to
exercise the Licensed Rights in the Adapted Material
under the conditions of the Adapter's License You apply.
c. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties, including when
the Licensed Material is used other than for NonCommercial
purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share
Adapted Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or
later, or a BY-NC-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition
in any reasonable manner based on the medium, means, and
context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms
or conditions on, or apply any Effective Technological
Measures to, Adapted Material that restrict exercise of the
rights granted under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database for NonCommercial purposes
only;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material,
including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.
# 实质性对话框
#### [查看发布和更改日志](https://github.com/afollestad/material-dialogs/releases)
[![Android CI](https://github.com/afollestad/material-dialogs/workflows/Android%20CI/badge.svg)](https://github.com/afollestad/material-dialogs/actions?query=workflow%3A%22Android+CI%22)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a4acc30a9ce440087f7688735359bb8)](https://www.codacy.com/app/drummeraidan_50/material-dialogs?utm_source=github.com&utm_medium=referral&utm_content=afollestad/material-dialogs&utm_campaign=Badge_Grade)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
---
![Showcase](https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/showcase4.png)
# 模块
核心模块是使用此库所需的基本模块。其他是对 核心 的扩展。
请注意,由于材料对话 2。x.x,这个库只支持 Kotlin 。最新的 Java 版本是 `0.9.6.0`,可以找到 [here](README_OLD.md)。请注意,0.9.6.0 是不支持的,错误和改进将不会对该版本。
## Core
[ ![Core](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/core?label=core&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/core)
#### [核心教程和示例](documentation/CORE.md)
`core` 模块包含了启动库所需的所有内容。它包含所有核心和正常使用的功能。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic_with_buttons.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:core:3.3.0'
}
```
## 输入
[ ![Input](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/input?label=input&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/input)
#### [输入教程和示例](documentation/INPUT.md)
`input` 模块包含对核心模块的扩展,例如文本输入对话框。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/input.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:input:3.3.0'
}
```
## 档案
[ ![Files](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/files?label=files&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/files)
#### [文件教程和示例](documentation/FILES.md)
`files` 模块包含对核心模块的扩展,例如文件和文件夹选择器。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_chooser.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:files:3.3.0'
}
```
## 颜色
[ ![Color](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/color?label=color&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/color)
#### [颜色教程和示例](documentation/COLOR.md)
`color` 模块包含对核心模块的扩展,例如颜色选择器。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/color_chooser.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:color:3.3.0'
}
```
## 日期时间
[ ![DateTime](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/datetime?label=datetime&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/datetime)
#### [DateTime 教程和示例](documentation/DATETIME.md)
`datetime` 模块包含用于制作日期、时间和日期-时间选择器对话框的扩展。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/datetimepicker.png" width="500px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:datetime:3.3.0'
}
```
## 底页
[ ![Bottom Sheets](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/bottomsheets?label=bottomsheets&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/bottomsheets)
#### [底页教程和示例](documentation/BOTTOMSHEETS.md)
`bottomsheets` 模块包含将模态对话框转换为底部工作表的扩展,以及显示项目网格等其他功能。一定要为此签出样例项目!
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/bottomsheet_customview.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
}
```
## 生命周期
[ ![Lifecycle](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/lifecycle?label=lifecycle&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/lifecycle)
#### [生命周期教程和示例](documentation/LIFECYCLE.md)
`lifecycle` 模块包含使对话框与 AndroidX 生命周期一起工作的扩展。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:lifecycle:3.3.0'
}
```
# 材料对话框(pre2.0 版本,已弃用)
[ ![核心](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/core?label=core&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/core)
[ ![公地](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/commons?label=commons&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/commons)
[![Build Status](https://travis-ci.org/afollestad/material-dialogs.svg)](https://travis-ci.org/afollestad/material-dialogs)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a4acc30a9ce440087f7688735359bb8)](https://www.codacy.com/app/drummeraidan_50/material-dialogs?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=afollestad/material-dialogs&amp;utm_campaign=Badge_Grade)
[![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/afollestad/material-dialogs/blob/master/LICENSE.txt)
![Screenshots](https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/readmeshowcase.png)
# 目录(核心)
1. [样例项目](https://github.com/afollestad/material-dialogs#sample-project)
2. [Gradle 依赖](https://github.com/afollestad/material-dialogs#gradle-dependency)1。[](https://github.com/afollestad/material-dialogs#repository)2。[Core](https://github.com/afollestad/material-dialogs#core)3。[Commons](https://github.com/afollestad/material-dialogs#commons)
3. [有什么新鲜事吗?](https://github.com/afollestad/material-dialogs#whats-new)
4. [基本对话框](https://github.com/afollestad/material-dialogs#basic-dialog)
5. [取消对话框](https://github.com/afollestad/material-dialogs#dismissing-dialogs)
6. [显示图标](https://github.com/afollestad/material-dialogs#displaying-an-icon)
7. [堆叠动作按钮](https://github.com/afollestad/material-dialogs#stacked-action-buttons)1。[堆叠行为](https://github.com/afollestad/material-dialogs#stacking-behavior)
8. [中性动作按钮](https://github.com/afollestad/material-dialogs#neutral-action-button)
9. [回调](https://github.com/afollestad/material-dialogs#callbacks)
10. [复选框提示](https://github.com/afollestad/material-dialogs#checkbox-prompts)
11. [列出对话框](https://github.com/afollestad/material-dialogs#list-dialogs)
12. [单项选择列表对话框](https://github.com/afollestad/material-dialogs#single-choice-list-dialogs)1。[着色单选按钮](https://github.com/afollestad/material-dialogs#coloring-radio-buttons)
13. [多项选择列表对话框](https://github.com/afollestad/material-dialogs#multi-choice-list-dialogs)1。[着色复选框](https://github.com/afollestad/material-dialogs#coloring-check-boxes)
14. [将 IDS 分配给列表项视图](https://github.com/afollestad/material-dialogs#assigning-ids-to-list-item-views)
15. [自定义列表对话框](https://github.com/afollestad/material-dialogs#custom-list-dialogs)
16. [自定义视图](https://github.com/afollestad/material-dialogs#custom-views)1。[以后的访问](https://github.com/afollestad/material-dialogs#later-access)
17. [字体](https://github.com/afollestad/material-dialogs#typefaces)
18. [获取和设置动作按钮](https://github.com/afollestad/material-dialogs#getting-and-setting-action-buttons)
19. [主题化](https://github.com/afollestad/material-dialogs#theming)1。[基础知识](https://github.com/afollestad/material-dialogs#basics)2。[颜色](https://github.com/afollestad/material-dialogs#colors)3。[选择器](https://github.com/afollestad/material-dialogs#selectors)4。[重力](https://github.com/afollestad/material-dialogs#gravity)5。[材料调色板](https://github.com/afollestad/material-dialogs#material-palette)
20. [全球主题](https://github.com/afollestad/material-dialogs#global-theming)
21. [显示、取消和取消回调](https://github.com/afollestad/material-dialogs#show-cancel-and-dismiss-callbacks)
22. [输入对话框](https://github.com/afollestad/material-dialogs#input-dialogs)1。[为 EditText 着色](https://github.com/afollestad/material-dialogs#coloring-the-edittext)2。[限制输入长度](https://github.com/afollestad/material-dialogs#limiting-input-length)3。[自定义失效](https://github.com/afollestad/material-dialogs#custom-invalidation)
23. [进度对话框](https://github.com/afollestad/material-dialogs#progress-dialogs)1。[ProGuard ](https://github.com/afollestad/material-dialogs#proguard)2。[不确定进度对话框](https://github.com/afollestad/material-dialogs#indeterminate-progress-dialogs)3。[确定进度对话框](https://github.com/afollestad/material-dialogs#determinate-seek-bar-progress-dialogs)4。[在水平方向上创建一个不确定的对话框](https://github.com/afollestad/material-dialogs#make-an-indeterminate-dialog-horizontal)5。[为进度条着色](https://github.com/afollestad/material-dialogs#coloring-the-progress-bar)6。[自定义编号和进度格式](https://github.com/afollestad/material-dialogs#custom-number-and-progress-formats)
24. [Tint Helper ](https://github.com/afollestad/material-dialogs#tint-helper)
25. [Misc ](https://github.com/afollestad/material-dialogs#misc)
# 目录(Commons)
1. [颜色选择对话框](https://github.com/afollestad/material-dialogs#color-chooser-dialogs)1。[寻找可见的对话框](https://github.com/afollestad/material-dialogs#finding-visible-dialogs)2。[用户颜色输入](https://github.com/afollestad/material-dialogs#user-color-input)
2. [文件选择器对话框](https://github.com/afollestad/material-dialogs#file-selector-dialogs)
3. [文件夹选择器对话框](https://github.com/afollestad/material-dialogs#folder-selector-dialogs)
4. [偏好对话框](https://github.com/afollestad/material-dialogs#preference-dialogs)
5. [简单列表对话框](https://github.com/afollestad/material-dialogs#simple-list-dialogs)
------
# Sample Project
你可以从这里库下载最新的示例 APK:https://github.com/afollestad/ material-dialogs /blob/master/sample/sample.apk
它也在 Google Play 上:
<a href="https://play.google.com/store/apps/details?id=com.afollestad.materialdialogssample" target="_blank">
<img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" height="60"/>
</a>
安装示例项目是了解新版本的一个好方法。尽管观看这篇文章库将允许 Github 在我发布新闻稿时给你发电子邮件。
---
# Gradle 依赖
### Repository
Gradle 依赖项可通过 [jCenter](https://bintray.com/drummer-aidan/maven/material-dialogs:core/view) 获得。JCenter 是 Android Studio 使用的默认 Maven库。
此库支持的最小 API 级别是 API14。
### Core
核心模块包含了这个库的所有主要类,包括 `MaterialDialog`。你可以使用 Core 创建基本的、列表的、单 / 多选择的、进度的、输入的等对话框。
```gradle
dependencies {
// ... other dependencies here
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
}
```
### Commons
Commons 模块包含对库的扩展,并不是每个人都可能需要。这包括 `ColorChooserDialog``FolderChooserDialog`,材料 `Preference` 类,以及 `MaterialSimpleListAdapter`/`materialsimplelistitem`
```gradle
dependencies {
// ... other dependencies here
implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
}
```
新的扩展很可能会在以后添加到 Commons 中。
---
# What's New
请参阅项目的发布页面,获取带有更改日志的版本列表。
### [View Releases](https://github.com/afollestad/material-dialogs/releases)
如果你看了这个库,每次我发布更新时,GitHub 都会给你发一封电子邮件。
---
# Basic Dialog
首先,注意 `MaterialDialog` 扩展了 `DialogBase`,这扩展了 `android.app.Dialog`
下面是一个基本的示例,它模仿了你在 Google 的材料设计指南中看到的对话框(这里是:http://www.google.com/design/spec/components/dialogs.html#dialogs-usage)。请注意,对于接受字符串的方法,总是可以用文字字符串和字符串资源代替,对于颜色资源也是一样(例如 `titleColor``titleColorRes`)。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.negativeText(R.string.disagree)
.show();
```
你的活动需要继承 Appcompat 主题,以便正确地处理此库。材质对话框将自动将 `positiveColor`(用于正向操作按钮)与 styles.xml 主题的 `colorAccent` 属性匹配。
如果内容足够长,它将变得可以滚动,并且在操作按钮上方将显示一个分隔符。
---
# 取消对话框
我遇到过很多问题,问你如何拒绝对话。它的工作方式与 `AlertDialog` 相同,因为 `AlertDialog``MaterialDialog` 都是 `android.app.Dialog` 的实例(这就是 `dismiss()``show()` 的来源)。不能使用 `Builder` 取消对话框。你只能使用对话框本身来取消对话框。
有很多方法可以得到 `MaterialDialog` 的实例。两种主要的方法是通过 `show()``build()` 的方法 `MaterialDialog.Builder`
通过 `show()`,它立即显示对话框并返回可见的对话框:
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.show();
```
通过 `build()`,它只构建对话框,但不显示它,直到你这么说:
```java
MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree);
MaterialDialog dialog = builder.build();
dialog.show();
```
一旦显示了对话框,你就可以取消它:
```java
dialog.dismiss();
```
还有其他不同的地方给出了 `MaterialDialog` 实例,例如在下面的将来部分中讨论的一些回调中。
---
# 显示图标
MaterialDialog 支持显示一个图标,就像 Stock AlertDialog 一样;它将转到标题的左侧。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.icon(R.drawable.icon)
.show();
```
你可以使用 `limitIconToDefaultSize()``maxIconSize(int size)``maxIconSizeRes(int sizeRes)`Builder 方法来限制图标的最大大小。
---
# 堆叠动作按钮
如果你有多个动作按钮在一起太宽,不适合在一条线上,对话框将堆叠按钮,以垂直方向。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.longer_positive)
.negativeText(R.string.negative)
.show();
```
### 堆叠行为
你可以从 `Builder` 设置堆叠行为:
```java
new MaterialDialog.Builder(this)
...
.stackingBehavior(StackingBehavior.ADAPTIVE) // the default value
.show();
```
---
# 中性动作按钮
除了肯定和否定的文本外,你还可以指定中性文本。它将显示最左翼的中立行动。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.negativeText(R.string.disagree)
.neutralText(R.string.more_info)
.show();
```
---
# Callbacks
从 0.8.2.0 版本开始,`callback()`Builder 方法已被弃用,取而代之的是下面讨论的各个回调方法。更早的版本仍然需要使用 `ButtonCallback`
要知道用户何时选择动作按钮,你需要设置回调:
```java
new MaterialDialog.Builder(this)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
})
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
})
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
});
```
如果你正在监听这三个动作按钮,你可以只使用 `onAny()``which` 参数将告诉你按下了哪个按钮。
如果 `autoDismiss` 已关闭,那么你必须手动取消这些回调中的对话框。默认情况下,自动删除是打开的。
---
# 复选框提示
复选框提示允许你显示一个 UI,类似于 Android 在 API23+ 上请求权限时使用的 UI。
注意:你也可以在列表对话框和输入对话框中使用复选框提示。
```java
new MaterialDialog.Builder(this)
.iconRes(R.drawable.ic_launcher)
.limitIconToDefaultSize()
.title(R.string.example_title)
.positiveText(R.string.allow)
.negativeText(R.string.deny)
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
showToast("Prompt checked? " + dialog.isPromptCheckBoxChecked());
}
})
.checkBoxPromptRes(R.string.dont_ask_again, false, null)
.show();
```
---
# List Dialogs
创建一个列表对话框只需要传入一个字符串数组。回调(“itemscallback”)也很简单。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.items(R.array.items)
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
}
})
.show();
```
如果 `autoDismiss` 已关闭,则必须手动取消回调中的对话框。默认情况下,自动删除是打开的。你可以将 `positiveText()` 或其他操作按钮传递给构建器,以强制它显示列表下方的操作按钮,但是这仅在某些特定情况下有用。
---
# 单项选择列表对话框
单项选择列表对话框与常规列表对话框几乎相同。唯一的区别是,你使用 `itemsCallbackSingleChoice` 设置回调,而不是 `itemsCallback`。这表示对话框显示列表项旁边的单选按钮。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.items(R.array.items)
.itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
/**
* If you use alwaysCallSingleChoiceCallback(), which is discussed below,
* returning false here won't allow the newly selected radio button to actually be selected.
**/
return true;
}
})
.positiveText(R.string.choose)
.show();
```
如果你想预选一个项,请在 `itemsCallbackSingleChoice()` 中传递一个索引 0 或更大的值来代替-1。稍后,如果不使用自定义适配器,则可以在 `MaterialDialog` 实例上使用 `setSelectedIndex(int)` 更新选定的索引。
如果不使用 `positiveText()` 设置正向操作按钮,则当用户按下正向操作按钮时,对话框将自动调用单项选择回调。对话框也会自动删除,除非自动删除被关闭。
如果调用 `alwaysCallSingleChoiceCallback()`,则每当用户选择 / 取消某个项时,都会调用 single choice 回调。
## 着色单选按钮
与动作按钮和材质对话框中的许多其他元素一样,你可以自定义对话框中单选按钮的颜色。`Builder` 类包含一个 `widgetColor()``widgetColorRes()``widgetColorAttr()``choiceWidgetColor()` 方法。它们的名称和参数注释使它们不言自明。
`widgetColor` 是影响其他 UI 元素的相同颜色。`choiceWidgetColor` 是单选和多选对话框特有的,它只影响单选按钮和复选框。你提供的是 `ColorStateList`,而不是用于生成 `ColorStateList` 的单一颜色。
请注意,默认情况下,单选按钮将使用活动主题中的 `colorAccent`(用于 AppCompat)或 `android:colorAccent`(用于材料主题)中的颜色进行着色。
还有一个全局主题化属性,如本文自述的全局主题化部分所示:`md_widget_color`
---
# 多项选择列表对话框
多项选择列表对话框与常规列表对话框几乎相同。唯一的区别是,你使用 `itemsCallbackMultiChoice` 设置回调,而不是 `itemsCallback`。这表示对话框显示列表项旁边的复选框,回调可以返回多个选择。
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.items(R.array.items)
.itemsCallbackMultiChoice(null, new MaterialDialog.ListCallbackMultiChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text) {
/**
* If you use alwaysCallMultiChoiceCallback(), which is discussed below,
* returning false here won't allow the newly selected check box to actually be selected
* (or the newly unselected check box to be unchecked).
* See the limited multi choice dialog example in the sample project for details.
**/
return true;
}
})
.positiveText(R.string.choose)
.show();
```
如果要预选任何项,请在 `itemsCallbackMultiChoice()` 中传递一个索引(资源或文字)数组来代替 null。稍后,如果不使用自定义适配器,则可以在 `MaterialDialog` 实例上使用 `setSelectedIndices(Integer[])` 更新选定的索引。
如果你没有使用 `positiveText()` 设置一个积极的动作按钮,当用户按下积极的动作按钮时,对话框将自动调用多项选择回调。对话框也会自动删除,除非自动删除被关闭。
如果调用 `alwaysCallMultiChoiceCallback()`,则每当用户选择 / 取消选择一个项时,都会调用多选择回调。
## 着色复选框
与动作按钮和材质对话框中的许多其他元素一样,你可以自定义对话框复选框的颜色。`Builder` 类包含一个 `widgetColor()``widgetColorRes()``widgetColorAttr()``choiceWidgetColor()` 方法。它们的名称和参数注释使它们变得不言自明。
`widgetColor` 是影响其他 UI 元素的相同颜色。`choiceWidgetColor` 是单选和多选对话框特有的,它只影响单选按钮和复选框。你提供的是 `ColorStateList`,而不是用于生成 `ColorStateList` 的单一颜色。
请注意,默认情况下,单选按钮将使用活动主题中的 `colorAccent`(用于 AppCompat)或 `android:colorAccent`(用于材料主题)中的颜色进行着色。
还有一个全局主题化属性,如本文自述的全局主题化部分所示:`md_widget_color`
---
# 将 IDS 分配给列表项视图
如果需要通过 ID 而不是索引来保留列表项跟踪,则可以从整数数组中分配项目 ID:
```java
new MaterialDialog.Builder(this)
.title(R.string.socialNetworks)
.items(R.array.socialNetworks)
.itemsIds(R.array.itemIds)
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
Toast.makeText(Activity.this, which + ": " + text + ", ID = " + view.getId(), Toast.LENGTH_SHORT).show();
}
})
.show();
```
你还可以传递一个字面上的整数数组来代替数组资源 ID。
---
# 自定义列表对话框
与 Android 的本机对话框一样,你也可以通过 `.adapter()` 传入自己的适配器,以定制你希望列表工作的确切方式。
```java
new MaterialDialog.Builder(this)
.title(R.string.socialNetworks)
// second parameter is an optional layout manager. Must be a LinearLayoutManager or GridLayoutManager.
.adapter(new ButtonItemAdapter(this, R.array.socialNetworks), null)
.show();
```
注意,随着新版本的发布,材质对话框不再支持 `ListView``ListAdapter`。现在是每个人都使用 `RecyclerView` 的时候了。你的自定义适配器将不得不自行处理项目单击事件;这个库的类和示例项目提供了一些很好的示例,说明如何正确地完成这些操作。
如果需要访问 `RecyclerView`,可以使用 `MaterialDialog` 实例:
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
...
.build();
RecyclerView list = dialog.getRecyclerView();
// Do something with it
dialog.show();
```
请注意,你不需要使用自定义适配器来访问 `RecyclerView`,它可以用于单 / 多选择对话框、常规列表对话框等。
---
# Custom Views
自定义视图非常容易实现。
```java
boolean wrapInScrollView = true;
new MaterialDialog.Builder(this)
.title(R.string.title)
.customView(R.layout.custom_view, wrapInScrollView)
.positiveText(R.string.positive)
.show();
```
如果 `wrapInScrollView` 为真,那么库将把你的自定义视图放入滚动视图中。这允许用户在必要时滚动你的自定义视图(小屏幕、长内容等)。然而,在某些情况下,你并不想要这种行为。这主要包括在自定义布局中使用滚动视图的情况,包括列表视图、recyclerviews、Webviews、Gridviews 等。示例项目包含对此参数同时使用 true 和 false 的示例。
`wrapInScrollView` 为真时,你的自定义视图将自动在其周围放置填充。否则,你将负责使用看起来不错的填充值来填充你的内容。
## Later Access
如果在构建对话框后需要访问自定义视图中的一个视图,则可以使用 `getCustomView()``MaterialDialog`。如果你将布局资源传递给 `Builder`,这将特别有用,对话框将为你处理视图膨胀。
```java
MaterialDialog dialog = //... initialization via the builder ...
View view = dialog.getCustomView();
```
---
# Typefaces
如果你想使用自定义字体,可以在使用 `Builder` 时调用 `typeface(String, String)`。这将从项目的 `assets/fonts` 文件夹中的文件中提取字体。例如,如果在 `/src/main/assets/fonts` 中有 `Roboto.ttf``Roboto-Light.ttf`,则将调用 `typeface("Roboto.ttf", "Roboto-Light.ttf")`。此方法还将通过 `TypefaceHelper` 处理回收字体,你可以在自己的项目中使用该方法来避免重复分配。RAW`typeface(Typeface, Typeface)` 变体不会回收字体,每次调用都会重新分配该字体。
还有一个全局主题属性,可以自动将字体应用到应用程序中的每个材料对话框中。
---
# 获取和设置动作按钮
如果你希望在对话框构建和显示之后获得对其中一个对话框操作按钮的引用(例如,启用或禁用按钮):
```java
MaterialDialog dialog = //... initialization via the builder ...
View negative = dialog.getActionButton(DialogAction.NEGATIVE);
View neutral = dialog.getActionButton(DialogAction.NEUTRAL);
View positive = dialog.getActionButton(DialogAction.POSITIVE);
```
如果你想要更新对话框操作按钮的标题(你也可以传递一个字符串资源 ID 来代替文字字符串):
```java
MaterialDialog dialog = //... initialization via the builder ...
dialog.setActionButton(DialogAction.NEGATIVE, "New Title");
```
---
# Theming
在棒棒糖之前,如果不使用反射和自定义可拉伸,主题警报对话框基本上是不可能的。自 Kitkat 之后,Android 变得更加中性,但 AlertDialogs 继续使用 Holo Blue 作为标题和标题分隔符。棒棒糖的改进甚至更大,默认情况下,对话框中除了动作按钮外没有其他颜色。这使得主题化变得更加容易。
## Basics
默认情况下,材质对话框将基于从创建对话框的上下文中检索到的 `?android:textColorPrimary` 属性应用轻主题或暗主题。如果颜色是浅色(例如更白),它会猜测活动使用的是暗主题,它会使用对话框的暗主题。反之亦然的灯光主题。你可以从 `Builder#theme()` 方法手动设置所使用的主题:
```java
new MaterialDialog.Builder(this)
.content("Hi")
.theme(Theme.DARK)
.show();
```
或者,你也可以使用全局主题化属性,这将在下面的一节中讨论。全局主题避免了为你显示的每个对话框不断调用主题设置器。
## Colors
用这个库创建的对话框的几乎每个方面都可以着色:
```java
new MaterialDialog.Builder(this)
.titleColorRes(R.color.material_red_500)
.contentColor(Color.WHITE) // notice no 'res' postfix for literal color
.linkColorAttr(R.attr.my_link_color_attr) // notice attr is used instead of none or res for attribute resolving
.dividerColorRes(R.color.material_pink_500)
.backgroundColorRes(R.color.material_blue_grey_800)
.positiveColorRes(R.color.material_red_500)
.neutralColorRes(R.color.material_red_500)
.negativeColorRes(R.color.material_red_500)
.widgetColorRes(R.color.material_red_500)
.buttonRippleColorRes(R.color.material_red_500)
.show();
```
这些名字在很大程度上是不言自明的。在本教程的其他章节中讨论的 `widgetColor` 方法适用于进度条、复选框和单选按钮。还需要注意的是,这些方法中的每一种都有 3 种变体,用于直接设置颜色、使用颜色资源和使用颜色属性。
## Selectors
选择器是当被按下或聚焦时改变状态的可读物。
```java
new MaterialDialog.Builder(this)
.btnSelector(R.drawable.custom_btn_selector)
.btnSelector(R.drawable.custom_btn_selector_primary, DialogAction.POSITIVE)
.btnSelectorStacked(R.drawable.custom_btn_selector_stacked)
.listSelector(R.drawable.custom_list_and_stackedbtn_selector)
.show();
```
第一个 `btnSelector` 行设置了一个可绘制的选择器,用于所有动作按钮。第二个 `btnSelector` 行复写了仅用于正按钮的可画项。这就导致了正向按钮与中性和负向按钮具有不同的选择器。`btnSelectorStacked` 设置一个可拉伸的选择器,当按钮堆叠时使用,要么是因为没有足够的空间将它们全部放在一行上,要么是因为你在 `Builder` 上使用了 `forceStacked(true)``listSelector` 用于列表项,当你不使用自定义适配器时。
注:
与使用自定义动作按钮选择器有关的一个重要注意事项:确保你的选择器可拉引用像默认的可拉引用一样插入可拉引用-这对于正确的动作按钮填充很重要。
## Gravity
你可能不太可能想在对话框中改变元素的重力,但这是有可能的。
```java
new MaterialDialog.Builder(this)
.titleGravity(GravityEnum.CENTER)
.contentGravity(GravityEnum.CENTER)
.btnStackedGravity(GravityEnum.START)
.itemsGravity(GravityEnum.END)
.buttonsGravity(GravityEnum.END)
.show();
```
这些都是不言自明的。`titleGravity` 设置对话标题的重力,`contentGravity` 设置对话内容的重力,`btnStackedGravity` 设置堆叠动作按钮的重力,`itemsGravity` 设置列表项的重力(当你不使用自定义适配器时)。
for,`buttonsGravity` 请参见:
<table>
<tr>
<td><b>START (Default)</b></td>
<td>Neutral</td>
<td>Negative</td>
<td>Positive</td>
</tr>
<tr>
<td><b>CENTER</b></td>
<td>Negative</td>
<td>Neutral</td>
<td>Positive</td>
</tr>
<tr>
<td><b>END</b></td>
<td>Positive</td>
<td>Negative</td>
<td>Neutral</td>
</tr>
</table>
没有正按钮时,负按钮就占了它的位置,只有中间的按钮除外。
## 材料调色板
要查看适合材料设计调色板的颜色,请参见以下页面:http://www.google.com/design/spec/style/color.html#color-color-palette
---
# Global Theming
以上小节中讨论的主题方面的大部分内容都可以自动应用到你在具有包含以下任何属性的主题的活动中显示的所有对话框中:
```xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!--
All dialogs will default to Theme.DARK with this set to true.
-->
<item name="md_dark_theme">true</item>
<!--
This overrides the default dark or light dialog background color.
Note that if you use a dark color here, you should set md_dark_theme to
true so text and selectors look visible
-->
<item name="md_background_color">#37474F</item>
<!--
Applies an icon next to the title in all dialogs.
-->
<item name="md_icon">@drawable/ic_launcher</item>
<!--
Limit icon to a max size.
-->
<attr name="md_icon_max_size" format="dimension" />
<!--
Limit the icon to a default max size (48dp).
-->
<attr name="md_icon_limit_icon_to_default_size" format="boolean" />
<!--
By default, the title text color is derived from the
?android:textColorPrimary system attribute.
-->
<item name="md_title_color">#E91E63</item>
<!--
By default, the content text color is derived from the
?android:textColorSecondary system attribute.
-->
<item name="md_content_color">#9C27B0</item>
<!--
By default, the link color is derived from the colorAccent attribute
of AppCompat or android:colorAccent attribute of the Material theme.
-->
<item name="md_link_color">#673AB7</item>
<!--
By default, the positive action text color is derived
from the colorAccent attribute of AppCompat or android:colorAccent
attribute of the Material theme.
-->
<item name="md_positive_color">#673AB7</item>
<!--
By default, the neutral action text color is derived
from the colorAccent attribute of AppCompat or android:colorAccent
attribute of the Material theme.
-->
<item name="md_neutral_color">#673AB7</item>
<!--
By default, the negative action text color is derived
from the colorAccent attribute of AppCompat or android:colorAccent
attribute of the Material theme.
-->
<item name="md_negative_color">#673AB7</item>
<!--
By default, a progress dialog's progress bar, check boxes, and radio buttons
have a color that is derived from the colorAccent attribute of AppCompat or
android:colorAccent attribute of the Material theme.
-->
<item name="md_widget_color">#673AB7</item>
<!--
By default, the list item text color is black for the light
theme and white for the dark theme.
-->
<item name="md_item_color">#9C27B0</item>
<!--
This overrides the color used for the top and bottom dividers used when
content is scrollable
-->
<item name="md_divider_color">#E91E63</item>
<!--
This overrides the color used for the ripple displayed on action buttons (Lollipop and above).
Defaults to the colorControlHighlight attribute from AppCompat OR the Material theme.
-->
<item name="md_btn_ripple_color">#E91E63</item>
<!--
This overrides the selector used on list items.
-->
<item name="md_list_selector">@drawable/selector</item>
<!--
This overrides the selector used on stacked action buttons.
-->
<item name="md_btn_stacked_selector">@drawable/selector</item>
<!--
This overrides the background selector used on the positive action button.
-->
<item name="md_btn_positive_selector">@drawable/selector</item>
<!--
This overrides the background selector used on the neutral action button.
-->
<item name="md_btn_neutral_selector">@drawable/selector</item>
<!--
This overrides the background selector used on the negative action button.
-->
<item name="md_btn_negative_selector">@drawable/selector</item>
<!--
This sets the gravity used while displaying the dialog title, defaults to start.
Can be start, center, or end.
-->
<item name="md_title_gravity">start</item>
<!--
This sets the gravity used while displaying the dialog content, defaults to start.
Can be start, center, or end.
-->
<item name="md_content_gravity">start</item>
<!--
This sets the gravity used while displaying the list items (not including custom adapters), defaults to start.
Can be start, center, or end.
-->
<item name="md_items_gravity">start</item>
<!--
This sets the gravity used while displaying the dialog action buttons, defaults to start.
START (Default) Neutral Negative Positive
CENTER: Negative Neutral Positive
END: Positive Negative Neutral
-->
<item name="md_buttons_gravity">start</item>
<!--
This sets the gravity used while displaying the stacked action buttons, defaults to end.
Can be start, center, or end.
-->
<item name="md_btnstacked_gravity">end</item>
<!--
The name of font in assets/fonts used on titles and action buttons
(null uses device default). E.g. [your-project]/app/main/assets/fonts/[medium]
-->
<item name="md_medium_font">Roboto-Medium.ttf</item>
<!--
The name of font in assets/fonts used everywhere else, like content and list items
(null uses device default). E.g. [your-project]/app/main/assets/fonts/[regular]
-->
<item name="md_regular_font">Roboto-Regular.ttf</item>
</style>
```
动作按钮的颜色也来自于 Material 主题的 `android:colorAccent` 属性,或者 AppCompat Material 主题的 `colorAccent` 属性,如示例项目中所示。手动设置颜色将覆盖该行为。
---
# 显示、取消和取消回调
你可以直接从 `Builder` 而不是在结果 `MaterialDialog` 实例上设置 show/cancel/discound 侦听器。
还要注意,`Builder` 有一个 `cancelable()` 方法,当你在对话框窗口外点击时,可以禁用该对话框。
```java
new MaterialDialog.Builder(this)
.title("Use Google's Location Services?")
.content("Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.")
.positiveText("Agree")
.showListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
}
})
.cancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
}
})
.dismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
})
.show();
```
---
# Input Dialogs
输入对话框很容易解释,它通过输入字段(EditText)从应用程序的用户那里检索输入。如果需要,还可以在 EditText 上面显示内容。
```java
new MaterialDialog.Builder(this)
.title(R.string.input)
.content(R.string.input_content)
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)
.input(R.string.input_hint, R.string.input_prefill, new MaterialDialog.InputCallback() {
@Override
public void onInput(MaterialDialog dialog, CharSequence input) {
// Do something
}
}).show();
```
输入对话框将自动处理对焦 EditText 和显示键盘,以允许用户立即输入。当对话框关闭时,键盘将自动关闭。
请注意,当对话框按下输入时,将强制显示“积极行动”按钮,将输入提交给回调。
还要注意,对 `inputType()` 的调用是可选的。
## 为 EditText 着色
与动作按钮和材料对话框中的许多其他元素一样,你可以自定义输入对话框 `EditText` 的颜色。`Builder` 类包含一个 `widgetColor()``widgetColorRes()``widgetColorAttr()` 方法。它们的名称和参数注释使它们不言自明。请注意,默认情况下,EditTexts 将使用活动主题中的 `colorAccent`(用于 AppCompat)或 `android:colorAccent`(用于材料主题)中的颜色进行着色。
还有一个全局主题化属性,如本文自述的全局主题化部分所示:`md_widget_color`
## 限制输入长度
下面的代码将在输入对话框中显示一个小指示器,告诉用户他们输入了多少字符。如果输入少于 2 个字符或超过 20 个字符,对话框将不允许提交输入。它还将为输入字段和字符计数器着色,以错误的颜色传递给第三个参数。
如果最小长度超过 0,就不会有最小长度。如果你通过-1 的最大长度,将没有最大长度。如果根本不传递第三个参数,它将默认为“材料红色”。
```java
new MaterialDialog.Builder(this)
.title(R.string.input)
.inputRangeRes(2, 20, R.color.material_red_500)
.input(null, null, new MaterialDialog.InputCallback() {
@Override
public void onInput(MaterialDialog dialog, CharSequence input) {
// Do something
}
}).show();
```
* 请注意,`inputRangeRes(int, int, int)` 为第三个参数获取一个颜色资源 ID,而 `inputRange(int, int, int)` 为第二个参数获取一个文字颜色整数。你可以使用其中一个,或者使用完全不需要第三个参数的变量。
## 自定义失效
使输入对话框无效(基于你认为输入是否可接受而启用或禁用 EditText)的最简单方法是从 `Builder` 调用 `alwaysCallInputCallback()`,以便每当用户更改输入时都调用回调。从那里,你可以不断地检查他们输入了什么。如果你决定他们不能提交它,那么你可以在回调中禁用 Submit 按钮:
```java
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
```
---
# 进度对话框
这个库允许你显示带有材质设计的进度对话框,甚至可以使用你的应用程序的重音颜色为进度条着色(如果你使用 AppCompat 为你的应用程序或棒棒糖上的材质主题设置主题)。
## Proguard
通常,`ObjectAnimator` 在它在此库中使用的上下文中(用于自定义进度拖拽)将需要特殊的 ProGuard 规则,以便当你的应用程序构建为发布模式时,某些元素不会被删除。幸运的是,AAR 包可以指定 ProGuard 规则,这些规则被包含在依赖它们的应用程序中。因此,你不必担心包含任何 ProGuard 规则,以确保进度条表现良好。
## 不确定进度对话框
这将显示带有旋转圆圈的经典进度对话框,请查看示例项目以查看其实际运行情况:
```java
new MaterialDialog.Builder(this)
.title(R.string.progress_dialog)
.content(R.string.please_wait)
.progress(true, 0)
.show();
```
## 确定进度对话框
如果对话框不是不确定的,它会显示一个水平进度条,该进度条会增加到最大值。代码中的注释解释了它的作用。
```java
// Create and show a non-indeterminate dialog with a max value of 150
// If the showMinMax parameter is true, a min/max ratio will be shown to the left of the seek bar.
boolean showMinMax = true;
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.progress_dialog)
.content(R.string.please_wait)
.progress(false, 150, showMinMax)
.show();
// Loop until the dialog's progress value reaches the max (150)
while (dialog.getCurrentProgress() != dialog.getMaxProgress()) {
// If the progress dialog is cancelled (the user closes it before it's done), break the loop
if (dialog.isCancelled()) break;
// Wait 50 milliseconds to simulate doing work that requires progress
try {
Thread.sleep(50);
} catch (InterruptedException e) {
break;
}
// Increment the dialog's progress by 1 after sleeping for 50ms
dialog.incrementProgress(1);
}
// When the loop exits, set the dialog content to a string that equals "Done"
dialog.setContent(getString(R.string.done));
```
请参阅此对话框中的示例项目,并添加了线程。
## 在水平方向上创建一个不确定的对话框
默认情况下,不确定进度对话框使用循环进度指示器。从 `Builder` 中,你可以告诉对话框在显示不确定的进度对话框时需要使用水平指示器:
```java
new MaterialDialog.Builder(this)
.title(R.string.progress_dialog)
.content(R.string.please_wait)
.progress(true, 0)
.progressIndeterminateStyle(true)
.show();
```
## 为进度条着色
与动作按钮和材料对话框中的许多其他元素一样,你可以自定义进度对话框中进度条的颜色。`Builder` 类包含一个 `widgetColor()``widgetColorRes()``widgetColorAttr()` 方法。它们的名称和参数注释使它们不言自明。请注意,默认情况下,进度条将使用活动主题中的 `colorAccent`(用于 AppCompat)或 `android:colorAccent`(用于材料主题)中的颜色进行着色。
还有一个全局主题化属性,如本文自述的全局主题化部分所示:`md_widget_color`
## 自定义编号和进度格式
与股票 `ProgressDialog` 类似,你可以格式化进度 min/max 数字和确定对话框的百分比指示器。
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
.progress(false, 150, true)
...
.progressNumberFormat("%1d/%2d")
.progressPercentFormat(NumberFormat.getPercentageInstance())
...
.show();
```
上面传递的值是默认值。
---
# Tint Helper
你可以使用 `MDTintHelper` 类来动态地为复选框、单选按钮、编辑文本和进度条着色(以避免在运行时无法更改 `styles.xml`)。它在库中用于动态地为 UI 元素着色,以匹配你的设置 `widgetColor`
---
# Misc
如果你不希望在按下操作按钮或用户选择列表项时自动取消对话框:
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
// ... other initialization
.autoDismiss(false)
.show();
```
---
# 颜色选择对话框
构建器是这样使用的:
```java
// Pass a context, along with the title of the dialog
new ColorChooserDialog.Builder(this, R.string.color_palette)
.titleSub(R.string.colors) // title of dialog when viewing shades of a color
.accentMode(accent) // when true, will display accent palette instead of primary palette
.doneButton(R.string.md_done_label) // changes label of the done button
.cancelButton(R.string.md_cancel_label) // changes label of the cancel button
.backButton(R.string.md_back_label) // changes label of the back button
.preselect(accent ? accentPreselect : primaryPreselect) // optionally preselects a color
.dynamicButtonColor(true) // defaults to true, false will disable changing action buttons' color to currently selected color
.show(this); // an AppCompatActivity which implements ColorCallback
```
你在对话框中显示的活动 / 片段必须实现 `ColorCallback`:
```java
public class MyActivity implements ColorChooserDialog.ColorCallback {
// ...
@Override
public void onColorSelection(ColorChooserDialog dialog, @ColorInt int color) {
// TODO
}
}
```
---
如果不想使用内置的主色或重色调色板(由整个材质设计调色板组成),还可以指定要显示的自定义颜色:
```java
int[] primary = new int[] {
Color.parseColor("#F44336")
};
int[][] secondary = new int[][] {
new int[] { Color.parseColor("#EF5350"), Color.parseColor("#F44336"), Color.parseColor("#E53935") }
};
new ColorChooserDialog.Builder(this, R.string.color_palette)
.titleSub(R.string.colors)
.customColors(primary, secondary)
.show(this);
```
原色的第一个参数也可以使用一个数组资源,这可以在示例项目中看到。如果你为第二个参数传递 `null`,那么对于顶级颜色将不会显示子级别。
## 寻找可见的对话框
由于 `ColorChooserDialog``DialogFragment`,因此它通过其 `FragmentManager` 附加到你的活动 / 片段上。`ColorChooserDialog` 有一个名为 `findVisible(AppCompatActivity, String)` 的实用工具方法,如果有可见的颜色选择器,该方法将找到一个可见的颜色选择器:
```java
ColorChooserDialog primary = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_PRIMARY);
ColorChooserDialog accent = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_ACCENT);
ColorChooserDialog custom = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_CUSTOM);
```
## 用户颜色输入
默认情况下,颜色选择器对话框允许用户使用 RGB 滑块或十六进制输入字段输入自定义颜色。如果你不希望用户能够使用它,则可以禁用此功能:
```java
new ColorChooserDialog.Builder(this, R.string.color_palette)
.allowUserColorInput(false)
.customButton(R.string.md_custom_label)
.presetsButton(R.string.md_presets_label)
.show(this);
```
如果你希望用户能够输入自定义颜色,但不希望他们能够更改透明度(alpha):
```java
new ColorChooserDialog.Builder(this, R.string.color_palette)
.allowUserColorInputAlpha(false)
.customButton(R.string.md_custom_label)
.presetsButton(R.string.md_presets_label)
.show(this);
```
---
# 偏好对话框
Android 的 `EditTextPreference``ListPreference``MultiSelectListPreference` 允许你将首选项活动的设置与通过键入或选择接收到的用户输入相关联。Material Dialog 包括 `MaterialEditTextPreference``MaterialListPreference``MaterialMultiSelectListPreference` 类,可以在你的首选项 XML 中使用这些类来自动使用 Material-Themed Dialog。有关详细信息,请参见示例项目。
默认情况下,所有这些首选项类将把它们的布局设置为 `R.layout.md_preference_custom`。如果不希望设置默认布局,可以在 XML 中的首选项上提供一个属性:
```
app:useStockLayout="true"
```
---
# 文件选择器对话框
构建器是这样使用的:
```java
new FileChooserDialog.Builder(this)
.initialPath("/sdcard/Download") // changes initial path, defaults to external storage directory
.mimeType("image/*") // Optional MIME type filter
.extensionsFilter(".png", ".jpg") // Optional extension filter, will override mimeType()
.tag("optional-identifier")
.goUpLabel("Up") // custom go up label, default label is "..."
.show(this); // an AppCompatActivity which implements FileCallback
```
你在对话框中显示的活动 / 片段必须实现 `FileCallback`:
```java
public class MyActivity implements FileChooserDialog.FileCallback {
// ...
@Override
public void onFileSelection(FileChooserDialog dialog, File file) {
// TODO
final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
}
}
```
---
# 文件夹选择器对话框
构建器是这样使用的:
```java
// Pass AppCompatActivity which implements FolderCallback
new FolderChooserDialog.Builder(this)
.chooseButton(R.string.md_choose_label) // changes label of the choose button
.initialPath("/sdcard/Download") // changes initial path, defaults to external storage directory
.tag("optional-identifier")
.goUpLabel("Up") // custom go up label, default label is "..."
.show(this);
```
你在对话框中显示的活动 / 片段必须实现 `FolderCallback`:
```java
public class MyActivity implements FolderChooserDialog.FolderCallback {
// ...
@Override
public void onFolderSelection(FolderChooserDialog dialog, File folder) {
// TODO
final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
}
}
```
---
你可以选择允许用户从此对话框创建新的文件夹:
```java
new FolderChooserDialog.Builder(this)
.chooseButton(R.string.md_choose_label) // changes label of the choose button
.initialPath("/sdcard/Download") // changes initial path, defaults to external storage directory
.tag("optional-identifier")
.allowNewFolder(true, R.string.new_folder) // pass 0 in the second parameter to use default button label
.show(this);
```
---
# 简单列表对话框
简单列表对话框是一种特定风格的列表对话框,取自材料设计指南:https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
这个库的实现只是一个预先制作的适配器,你可以将其传递给 `MaterialDialog.Builder`
```java
final MaterialSimpleListAdapter adapter = new MaterialSimpleListAdapter(new MaterialSimpleListAdapter.Callback() {
@Override
public void onMaterialListItemSelected(MaterialDialog dialog, int index, MaterialSimpleListItem item) {
// TODO
}
});
adapter.add(new MaterialSimpleListItem.Builder(this)
.content("username@gmail.com")
.icon(R.drawable.ic_account_circle)
.backgroundColor(Color.WHITE)
.build());
adapter.add(new MaterialSimpleListItem.Builder(this)
.content("user02@gmail.com")
.icon(R.drawable.ic_account_circle)
.backgroundColor(Color.WHITE)
.build());
adapter.add(new MaterialSimpleListItem.Builder(this)
.content(R.string.add_account)
.icon(R.drawable.ic_content_add)
.iconPaddingDp(8)
.build());
new MaterialDialog.Builder(this)
.title(R.string.set_backup)
.adapter(adapter, null)
.show();
```
---
3.3.0
* 添加了 `md_line_spacing_body` 全局主题属性,该属性设置了消息行间距的全局默认值。见 #1903。
* 添加了一些断言和健全检查,以避免选择列表适配器出界崩溃。见 #1906。
* 底片对话框的底部不应使用角点半径。见 #1941。
* 修复用自定义字体切断的对话框标题。见 #1936。
* 如果 `noVerticalPadding` 设置为 `customView(...)``,则如果启用 `scrollable`,则不对内容 `ScrollView` 的底部应用填充。第 1834 号决议。
* 输入对话框样式不是由对话框强制执行的。使用 `TextInputLayout` 的全局默认值。见 #1857。
\ No newline at end of file
# 底页
## 目 录
1. [Gradle 依赖](#gradle-dependency)
2. [用法](#usage)
3. [布局模式](#layout-mode)
4. [窥视高度](#peek-height)
5. [项目网格](#item-grids)
6. [转角半径](#corner-radius)
---
## Gradle 依赖
[ ![Bottom Sheets](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/bottomsheets?label=bottomsheets&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/bottomsheets)
`bottomsheets` 模块包含将模态对话框转换为底部工作表的扩展,以及显示项目网格等其他功能。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:bottomsheets:3.2.1'
}
```
## Usage
使对话框成为底部工作表非常简单,只需将 `BottomSheet` 的构造实例作为第二个参数传递给 `MaterialDialog` 的构造函数。
```kotlin
MaterialDialog(this, BottomSheet()).show {
...
}
```
---
## Layout Mode
有两种布局模式:
* `MATCH_PARENT`-默认值。底片可以展开以填充屏幕的高度。当打开时,底片将处于其窥视高度。
* `WRAP_CONTENT`-底页只能扩展到它所包含的视图的高度。如果它包含的视图与屏幕一样高或更高,则它仅限于屏幕高度,在这种情况下,内容也应该在 `ScrollView` 中。
布局模式是在 `BottomSheet` 行为的构造函数中设置的,如果你希望使用 `MATCH_PARENT`,则根本不需要显式地设置它:
```kotlin
MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
...
}
```
---
## Peek Height
如果你以前使用过 Android 的底部工作表,窥探高度应该是一个熟悉的概念。窥视高度是指底板未完全展开时的高度。这是一个介于扩展和隐藏之间的点。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/bottomsheet_peekheight.gif" width="250px" />
默认的窥视高度是屏幕高度的 60%。如果你愿意,可以设置自定义的窥视高度:
```kotlin
val dialog = MaterialDialog(this, BottomSheet()).show {
setPeekHeight(res = R.dimen.my_default_peek_height)
}
// You can continue to make calls to this method, and changes are still animated
dialog.setPeekHeight(res = R.dimen.another_peek_height)
```
窥视高度的变化是动画为你服务的。如果你使用 `WRAP_CONTENT` 布局模式,则窥视高度被限制为底页的最大高度。
---
## Item Grids
由于在底部工作表中显示项目的网格是常见的,因此此模块包含一个实现此目的的方法。
```kotlin
val items = listOf(
BasicGridItem(R.drawable.some_icon, "One"),
BasicGridItem(R.drawable.another_icon, "Two"),
BasicGridItem(R.drawable.hello_world, "Three"),
BasicGridItem(R.drawable.material_dialogs, "Four")
)
MaterialDialog(this, BottomSheet()).show {
...
gridItems(items) { _, index, item ->
toast("Selected item ${item.title} at index $index")
}
}
```
请注意,如果你希望传递自定义项类型,`gridItems` 可以获取从 `GridItem` 接口继承的任何内容的列表。你只需要覆盖 `title` 值以及 `populateIcon(ImageView)`函数。
---
你可以提供一些额外的参数,其中大多数参数与你可以提供给 `listItems` 的参数相同。`customGridWidth` 是一个可选的整数资源,它允许你为网格设置宽度-你可以为不同的资源配置(平板电脑、景观等)设置不同的宽度。
```kotlin
fun gridItems(
items: List<IT : GridItem>,
@IntegerRes customGridWidth: Int? = null,
disabledIndices: IntArray? = null,
waitForPositiveButton: Boolean = true,
selection: GridItemListener<IT> = null
): MaterialDialog
```
---
### Corner Radius
这是取自核心模块文档。我在这里重申这一点是为了确保人们知道这是可能的,因为与常规的模态对话框相比,在底部工作表中使用舍入更常见。
角点半径可以通过应用程序主题中的一个属性进行全局更改。它默认为 4DP:
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
...
<item name="md_corner_radius">16dp</item>
</style>
```
上述功能会影响应用程序中的所有对话框,甚至是正常的模态对话框。对于该值还有一个编程设置器,你可以在每个对话框中使用它:
```kotlin
MaterialDialog(this, BottomSheet()).show {
// literal, internally converts to dp so 16dp
cornerRadius(16f)
// Using a dimen instead is encouraged as it's easier to have all instances changeable from one place
cornerRadius(res = R.dimen.my_corner_radius)
}
```
# 颜色
# 目录-颜色
1. [Gradle 依赖](#gradle-dependency)
2. [颜色选择器](#color-choosers)1。[基础知识](#basics)2。[副颜色](#sub-colors)
## Gradle 依赖
[ ![Color](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/color?label=color&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/color)
`color` 模块包含对核心模块的扩展,例如颜色选择器。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:color:3.2.1'
}
```
## Color Choosers
### Basics
颜色选择器显示简单的颜色网格。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/color_chooser.png" width="250px" />
```kotlin
val colors = intArrayOf(RED, GREEN, BLUE)
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(colors) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
你可以指定一个初始选择,它只是一个颜色整数:
```kotlin
val colors = intArrayOf(RED, GREEN, BLUE)
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(colors, initialSelection = BLUE) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
### Sub Colors
你可以指定子颜色,这些子颜色是从每个顶层颜色向下的一个级别。顶层数组的大小必须与子颜色数组的大小匹配。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/color_chooser_sub.png" width="250px" />
```kotlin
val colors = intArrayOf(RED, GREEN, BLUE) // size = 3
val subColors = listOf( // size = 3
intArrayOf(LIGHT_RED, RED, DARK_RED, WHITE),
intArrayOf(LIGHT_GREEN, GREEN, DARK_GREEN, GRAY),
intArrayOf(LIGHT_BLUE, BLUE, DARK_BLUE, BLACK)
)
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(colors, subColors = subColors) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
### ARGB 选择
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/custom_argb.png" width="250px" />
```kotlin
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(
colors = colors,
subColors = subColors,
allowCustomArgb = true,
showAlphaSelector = true
) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
省略 `showAlphaSelector` 将隐藏 alpha(透明)选择器。
# 核心
## 目 录
1. [Gradle 依赖](#gradle-dependency)
2. [基础知识](#basics)
3. [自定义消息](#customizing-the-message)
4. [动作按钮](#action-buttons)
5. [添加图标](#adding-an-icon)
6. [回调](#callbacks)
7. [Dismissing](#dismissing)
8. [列表](#lists)1。[平原](#plain)2。[单一选择](#single-choice)3。[多项选择](#multiple-choice)4。[Custom Adapters](#custom-adapters)
9. [复选框提示](#checkbox-prompts)
10. [自定义视图](#custom-views)
11. [杂项](#miscellaneous)
12. [主题化](#theming)1。[光明与黑暗](#light-and-dark)2。[背景颜色](#background-color)3。[波纹颜色](#ripple-color)4。[转角半径](#corner-radius)5。[文字颜色](#text-color)6。[字体](#fonts)7。[Widget Color](#widget-color)
## Gradle 依赖
[ ![Core](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/core?label=core&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/core)
`core` 模块包含了启动库所需的所有内容。它包含所有核心和正常使用的功能。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:core:3.2.1'
}
```
## Basics
下面是一个创建和显示对话框的基本示例:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic.png" width="250px" />
```kotlin
MaterialDialog(this).show {
title(R.string.your_title)
message(R.string.your_message)
}
```
`this` 应该是一个 `Context`,它连接到一个窗口,就像 `Activity`
如果你想要传入文字字符串而不是字符串资源:
```kotlin
MaterialDialog(this).show {
title(text = "Your Title")
message(text = "Your Message")
}
```
请注意,你也可以在不立即显示对话框的情况下设置对话框:
```kotlin
val dialog = MaterialDialog(this)
.title(R.string.your_title)
.message(R.string.your_message)
dialog.show()
```
## 自定义消息
`message`函数允许你使用 lambda 跟踪它,该 lambda 公开了某些内置的修饰符,并允许你直接对 `TextView` 进行操作。
```kotlin
MaterialDialog(this).show {
...
message(R.string.your_message) {
html() // format, color, etc. with tags in string
html { link -> // same as above, but...
// Invokes a callback when a URL is clicked instead of auto opening it in a browser
}
lineSpacing(1.4f) // modifies line spacing, default is 1.0f
// You can directly act on the message TextView as well
val textView = messageTextView
}
}
```
## Action Buttons
添加动作按钮的方法很简单:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic_with_buttons.png" width="250px" />
```kotlin
MaterialDialog(this).show {
positiveButton(R.string.agree)
negativeButton(R.string.disagree)
}
```
你也可以在这里使用文字字符串:
```kotlin
MaterialDialog(this).show {
positiveButton(text = "Agree")
negativeButton(text = "Disagree")
}
```
---
监听按钮的点击就像在末尾添加一个 lambda 一样简单:
```kotlin
MaterialDialog(this).show {
positiveButton(R.string.agree) { dialog ->
// Do something
}
negativeButton(R.string.disagree) { dialog ->
// Do something
}
}
```
如果动作按钮太长,不能与对话框的宽度相适应,它们将自动堆叠:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/stacked_buttons.png" width="250px" />
## Adding an Icon
你可以在标题的左侧显示一个图标:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/icon.png" width="250px" />
```kotlin
MaterialDialog(this).show {
icon(R.drawable.your_icon)
}
```
你还可以传递一个可拉伸实例:
```kotlin
val myDrawable: Drawable = // ...
MaterialDialog(this).show {
icon(drawable = myDrawable)
}
```
## Callbacks
有几个生命周期回调可以连接到:
```kotlin
MaterialDialog(this).show {
onPreShow { dialog -> }
onShow { dialog -> }
onDismiss { dialog -> }
onCancel { dialog -> }
}
```
## 解雇
取消对话框会关闭它,它只是从父类 `Dialog` 类继承的一个简单方法:
```kotlin
val dialog: MaterialDialog = // ...
dialog.dismiss()
```
---
你可以防止对话框被取消,这意味着必须通过操作按钮或调用上面的方法来明确地取消对话框。
```kotlin
MaterialDialog(this).show {
cancelable(false) // calls setCancelable on the underlying dialog
cancelOnTouchOutside(false) // calls setCanceledOnTouchOutside on the underlying dialog
}
```
## Lists
### Plain
你可以在 `MaterialDialog` 上使用 `listItems` 扩展来显示列表:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic_list.png" width="250px" />
```kotlin
MaterialDialog(this).show {
listItems(R.array.socialNetworks)
}
```
你也可以传递一个文字字符串数组:
```kotlin
val myItems = listOf("Hello", "World")
MaterialDialog(this).show {
listItems(items = myItems)
}
```
要获得项目选择事件,只需追加一个 lambda:
```kotlin
MaterialDialog(this).show {
listItems(R.array.socialNetworks) { dialog, index, text ->
// Invoked when the user taps an item
}
}
```
### Single Choice
你可以在 `MaterialDialog` 上使用 `listItemsSingleChoice` 扩展来显示单选(单选按钮)列表:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/single_choice_list.png" width="250px" />
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items)
}
```
你也可以传递一个文字字符串数组:
```kotlin
val myItems = listOf("Hello", "World")
MaterialDialog(this).show {
listItemsSingleChoice(items = myItems)
}
```
---
如果希望在对话框打开时选择一个选项,可以传递 `initialSelection` 索引):
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items, initialSelection = 1)
}
```
要获得项目选择事件,只需追加一个 lambda:
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items) { dialog, index, text ->
// Invoked when the user selects an item
}
}
```
在没有操作按钮的情况下,当用户点击一个项目时,会立即调用选择回调。如果你添加一个积极的行动按钮...
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items) { dialog, index, text ->
// Invoked when the user selects an item
}
positiveButton(R.string.select)
}
```
...然后,直到用户选择一个项目并点击“积极行动”按钮,才会调用回调。你可以使用 `waitForPositiveButton` 参数覆盖该行为。
额外的好处是,你可以禁用被选中 / 未选中的项目:
```kotlin
val indices = intArrayOf(0, 2)
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items, disabledIndices = indices)
}
```
---
在构建的对话框中,你可以使用一些方法来修改选中的状态:
```kotlin
val dialog: MaterialDialog = // ...
dialog.checkItem(index)
dialog.uncheckItem(index)
dialog.toggleItemChecked(index)
val checked: Boolean = dialog.isItemChecked(index)
```
### Multiple Choice
你可以在 `MaterialDialog` 上使用 `listItemsMultiChoice` 扩展来显示多项选择(复选框)列表:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/multi_choice_list.png" width="250px" />
```kotlin
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items) { _, index, text ->
// Invoked when the user selects item(s)
}
}
```
你也可以传递一个文字字符串数组:
```kotlin
val myItems = listOf("Hello", "World")
MaterialDialog(this).show {
listItemsMultiChoice(items = myItems)
}
```
---
如果希望在对话框打开时选择选项,可以传递 `initialSelection` 索引):
```kotlin
val indices = intArrayOf(1, 3)
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items, initialSelection = indices)
}
```
要获得项目选择事件,只需追加一个 lambda:
```kotlin
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items) { dialog, indices, items ->
// Invoked when the user selects an item
}
}
```
在没有操作按钮的情况下,当用户点击一个项目时,会立即调用选择回调。如果你添加一个积极的行动按钮...
```kotlin
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items) { dialog, indices, items ->
// Invoked when the user selects an item
}
positiveButton(R.string.select)
}
```
...然后,直到用户选择一个或多个项目并点击“积极行动”按钮,才会调用回调。你可以使用 `waitForPositiveButton` 参数覆盖该行为。
额外的好处是,你可以禁用被选中 / 未选中的项目:
```kotlin
val indices = intArrayOf(0, 2)
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items, disabledIndices = indices)
}
```
---
在构建的对话框中,你可以使用一些方法来修改选中的状态:
```kotlin
val dialog: MaterialDialog = // ...
val indices: IntArray = // ...
dialog.checkItems(indices)
dialog.uncheckItems(indices)
dialog.toggleItemsChecked(indices)
dialog.checkAllItems()
dialog.uncheckAllItems()
dialog.toggleAllItemsChecked()
val checked: Boolean = dialog.isItemChecked(index)
```
### 自定义适配器
如果希望自定义列表以使用自己的视图,则需要使用自定义适配器。
```kotlin
val adapter: RecyclerView.Adapter<*> = // some sort of adapter implementation...
MaterialDialog(this).show {
customListAdapter(adapter)
}
```
稍后可以从对话框实例中再次检索适配器:
```kotlin
val dialog: MaterialDialog = // ...
val adapter: RecyclerView.Adapter<*> = dialog.getListAdapter()
```
你还可以检索适配器托管在以下位置的 `RecyclerView`:
```kotlin
val dialog: MaterialDialog = // ...
val recyclerView: RecyclerView = dialog.getRecyclerView()
```
## 复选框提示
复选框提示可以与任何其他对话框类型一起使用,它将在显示操作按钮的同一视图中显示。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/checkbox_prompt.png" width="250px" />
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(R.string.your_label) { checked ->
// Check box was checked or unchecked
}
}
```
你也可以为标签传递一个文字字符串:
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(text = "Hello, World")
}
```
---
你还可以追加一个 lambda,该 lambda 在选中或未选中复选框时被调用:
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(text = "Hello, World") { checked -> }
}
```
如果你只关心按下“积极行动”按钮时的复选框状态:
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(R.string.your_label)
positiveButton(R.string.button_text) { dialog ->
val isChecked = dialog.isCheckPromptChecked()
// do something
}
}
```
## Custom Views
许多包含的扩展都使用自定义视图,例如颜色选择器对话框。在示例项目中还有一个简单的示例。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/custom_view.png" width="250px" />
```kotlin
MaterialDialog(this).show {
customView(R.layout.my_custom_view)
}
```
你还可以传递一个字面视图:
```kotlin
val myView: View = // ...
MaterialDialog(this).show {
customView(view = myView)
}
```
如果你的自定义视图可能比对话框更高,那么你将希望使其成为可滚动的:
```kotlin
MaterialDialog(this).show {
customView(R.layout.my_custom_view, scrollable = true)
}
```
对于以后的访问,你可以使用 `dialog.getCustomView()`:
```kotlin
val dialog = MaterialDialog(this)
.customView(R.layout.my_custom_view, scrollable = true)
val customView = dialog.getCustomView()
// Use the view instance, e.g. to set values or setup listeners
dialog.show()
```
## Miscellaneous
有一些细节很容易漏掉。例如,自动解除控制,无论按下操作按钮或点击列表项是否会自动解除对话框。默认情况下,它是打开的。你可以禁用它:
```kotlin
MaterialDialog(this).show {
noAutoDismiss()
}
```
## Theming
谷歌新的主题思维方式(相对于 2014 年的思维方式)是灵活的。如果你拿他们的
["Crane example"](https://material.io/design/components/dialogs.html#theming),你看到他们
更改字体、转角舍入等。
### Light and Dark
根据应用程序的主题,自动设置明暗主题(基本上是 `android:textColorPrimary` 是更亮还是更暗):
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/lightanddarkthemes.png" width="500px" />
### 背景颜色
Material Dialogs 在活动主题中使用 `colorBackgroundFloating` 属性的值作为 Dialogs 的背景色。你还可以在主题中使用 `md_background_color` 属性,该属性将优先使用。
### Ripple Color
Material Dialogs 默认情况下使用活动主题中的 `?android:colorControlHighlight` 属性的值作为列表项、按钮等的波纹颜色。你也可以使用 `md_ripple_color` 主题属性重写此内容。
### Corner Radius
角点半径是对话框角的舍入:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/customtheme.png" width="250px" />
它可以通过应用程序主题中的一个属性进行更改。它默认为 4DP:
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
<item name="md_corner_radius">16dp</item>
</style>
```
这个值也有一个编程设置器:
```kotlin
MaterialDialog(this).show {
// literal, internally converts to dp so 16dp
cornerRadius(16f)
// Using a dimen instead is encouraged as it's easier to have all instances changeable from one place
cornerRadius(res = R.dimen.my_corner_radius)
}
```
### Text Color
默认情况下,来自 ActivityTheme 的 `android:textColorPrimary``android:textColorSecondary` 属性用于对话框的标题和内容颜色。`colorPrimary` 用于动作按钮的默认文本颜色。如果你希望重写这些内容,可以提供以下属性:
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
<item name="md_color_title">@color/your_color</item>
<item name="md_color_content">@color/your_color</item>
<item name="md_color_button_text">@color/your/color</item>
</style>
```
### Fonts
这个库支持使用自定义字体,由支持库 `ResourcesCompat` 类提供支持。使用 `/res/font` 文件夹中的原始字体文件或 XML 字体文件,你可以使用应用程序主题中的属性在实质性对话框中使用它们。
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
<item name="md_font_title">@font/your_font</item>
<item name="md_font_body">@font/your_font</item>
<item name="md_font_button">@font/your_font</item>
</style>
```
请参阅示例项目中的“自定义主题”示例(打开主题切换器的溢出菜单)。
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/customtheme.png" width="250px" />
# 日期时间
## 目 录
1. [Gradle 依赖](#gradle-dependency-4)
2. [日期](#date)
3. [时间](#time)
4. [日期时间](#datetime)
## Gradle 依赖
[ ![DateTime](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/datetime?label=datetime&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/datetime)
`datetime` 模块包含用于制作日期、时间和日期-时间选择器对话框的扩展。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:datetime:3.2.1'
}
```
## Date
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/datepicker.png" width="250px" />
```kotlin
MaterialDialog(this).show {
...
datePicker { dialog, date ->
// Use date (Calendar)
}
}
```
还可以选择提供 `minDate``maxDate``currentDate` 参数。
## Time
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/timepicker.png" width="250px" />
```kotlin
MaterialDialog(this).show {
...
timePicker { dialog, time ->
// Use time (Calendar)
}
}
```
你还可以选择提供 `currentTime``show24HoursView` 参数。
## DateTime
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/datetimepicker.png" width="400px" />
```kotlin
MaterialDialog(this).show {
...
dateTimePicker(requireFutureDateTime = true) { _, dateTime ->
// Use dateTime (Calendar)
}
}
```
还可以选择提供 `minDateTime``maxDate``currentDateTime``show24HoursView``requireFutureDateTime` 参数。
# 档案
## 目 录
1. [Gradle 依赖](#gradle-dependency)
2. [文件选择器](#file-choosers)1。[基础知识](#basics)2。[过滤器](#filter)3。[空文本](#empty-text)4。[文件夹创建](#folder-creation)
3. [文件夹选择器](#folder-choosers)1。[基础知识](#basics-1)2。[过滤器](#filter-1)3。[空文本](#empty-text-1)4。[文件夹创建](#folder-creation-1)
## Gradle 依赖
[ ![Files](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/files?label=files&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/files)
`files` 模块包含对核心模块的扩展,例如文件和文件夹选择器。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:files:3.2.1'
}
```
## File Choosers
### Basics
注意:文件选择器要求你的应用程序具有 `READ_EXTERNAL_STORAGE` 的权限,否则目录列表将返回为空。
`MaterialDialog` 上使用 `fileChooser` 扩展名创建文件选择器:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_chooser.png" width="250px" />
```kotlin
MaterialDialog(this).show {
fileChooser { dialog, file ->
// File selected
}
}
```
它显示了所有的文件和文件夹,从外部存储目录开始。点击文件会调用回调并取消对话框。
你可以更改最初列出的目录:
```kotlin
val initialFolder = File(getExternalStorageDirectory(), "Download")
MaterialDialog(this).show {
fileChooser(initialDirectory = initialFolder) { dialog, file ->
// File selected
}
}
```
如果存在一个积极的行动按钮,点击一个文件将选择它,但回调是不是调用,直到积极的行动按钮被按下。
### Filter
可以应用一个过滤器来只显示你希望显示的文件和目录:
```kotlin
// show ALL folders, and files that start with the letter 'a'
val myFilter: FileFilter = { it.isDirectory || it.nameWithoutExtension.startsWith("a", true) }
MaterialDialog(this).show {
fileChooser(filter = myFilter) { dialog, file ->
// File selected
}
}
```
### Empty Text
当文件夹中没有内容时,将显示空文本。你可以配置空文本标签:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_emptytext.png" width="250px" />
```kotlin
MaterialDialog(this).show {
fileChooser(emptyTextRes = R.string.custom_label) { dialog, file ->
// File selected
}
}
```
### Folder Creation
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_folder_creation.png" width="250px" />
你可以允许用户创建文件夹。
```kotlin
MaterialDialog(this).show {
fileChooser(
allowFolderCreation = true,
folderCreationLabel = R.string.new_folder // optional as well
) { dialog, file ->
// File selected
}
}
```
此“新建文件夹”选项仅在可写的目录中显示。
## Folder Choosers
注意:文件夹选择器要求你的应用程序具有 `READ_EXTERNAL_STORAGE` 的权限,否则目录列表将返回为空。
文件夹选择器与文件选择器基本相同,但有几个小区别:1)即使应用了自定义过滤器,也只显示文件夹。2)选择回调不会在项目单击时调用,只有在按下“积极行动”按钮时,才会在当前查看的文件夹中调用它。
### Basics
```kotlin
MaterialDialog(this).show {
folderChooser { dialog, folder ->
// Folder selected
}
}
```
### Filter
你可以像使用文件选择器一样应用过滤器。
```kotlin
// show only folders that start with the letter 'a'
val myFilter: FileFilter = { it.name.startsWith("a", true) }
MaterialDialog(this).show {
folderChooser(filter = myFilter) { dialog, file ->
// Folder selected
}
}
```
### Empty Text
当文件夹中没有内容时,将显示空文本。你可以配置空文本标签:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_emptytext.png" width="250px" />
```kotlin
MaterialDialog(this).show {
folderChooser(emptyTextRes = R.string.custom_label) { dialog, file ->
// File selected
}
}
```
### Folder Creation
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_folder_creation.png" width="250px" />
你可以允许用户创建文件夹。
```kotlin
MaterialDialog(this).show {
folderChooser(
allowFolderCreation = true,
folderCreationLabel = R.string.new_folder // optional as well
) { dialog, file ->
// File selected
}
}
```
此“新建文件夹”选项仅在可写的目录中显示。
# 输入
## 目 录
1. [Gradle 依赖](#gradle-dependency)
2. [文本输入](#text-input)1。[基础知识](#basics)2。[提示和预置](#hints-and-prefill)3。[输入类型](#input-types)4。[最大长度](#max-length)5。[自定义验证](#custom-validation)
## Gradle 依赖
[ ![Input](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/input?label=input&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/input)
`input` 模块包含对核心模块的扩展,例如文本输入对话框。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:input:3.3.0'
}
```
## Text Input
### Basics
你可以在 `MaterialDialog` 上使用 `input` 扩展来设置输入对话框:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/input.png" width="250px" />
```kotlin
MaterialDialog(this).show {
input()
positiveButton(R.string.submit)
}
```
通过设置输入对话框,你可以检索输入字段:
```kotlin
val dialog: MaterialDialog = // ...
val inputField: EditText = dialog.getInputField()
```
---
当按下输入文本的“积极行动”按钮时,可以追加 lambda 以接收回调:
```kotlin
MaterialDialog(this).show {
input { dialog, text ->
// Text submitted with the action button
}
positiveButton(R.string.submit)
}
```
如果将 `waitForPositiveButton` 设置为 false,则每次修改文本字段时都会调用回调:
```kotlin
MaterialDialog(this).show {
input(waitForPositiveButton = false) { dialog, text ->
// Text changed
}
positiveButton(R.string.done)
}
```
即使输入为空,也可以按下“积极行动”按钮:
```kotlin
MaterialDialog(this).show {
input(allowEmpty = true) { dialog, text ->
// Text submitted with the action button, might be an empty string`
}
positiveButton(R.string.done)
}
```
### 提示和预置
你可以为输入字段设置一个提示,这是当字段为空时显示的灰色褪色文本:
```kotlin
MaterialDialog(this).show {
input(hintRes = R.string.hint_text)
}
```
也可以使用文字字符串:
```kotlin
MaterialDialog(this).show {
input(hint = "Your Hint Text")
}
```
---
你还可以对输入字段进行预填充:
```kotlin
MaterialDialog(this).show {
input(prefillRes = R.string.prefill_text)
}
```
也可以使用文字字符串:
```kotlin
MaterialDialog(this).show {
input(prefill = "Prefilled text")
}
```
### Input Types
你可以将输入类型应用到输入字段,当字段被关注时,输入字段会修改键盘类型。这是从 Android framework 开始的,输入类型被直接应用到底层 `EditText`:
```kotlin
val type = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
MaterialDialog(this).show {
input(inputType = type)
}
```
### Max Length
你可以设置一个最大长度,使字符计数器可见,如果输入长度超过该长度,则禁用“积极行动”按钮:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/input_max_length.png" width="250px" />
```kotlin
MaterialDialog(this).show {
input(maxLength = 8)
positiveButton(R.string.submit)
}
```
### 自定义验证
你可以使用 Input Listener 进行自定义验证。本例强制输入以字母“A”开头:
```kotlin
MaterialDialog(this).show {
input(waitForPositiveButton = false) { dialog, text ->
val inputField = dialog.getInputField()
val isValid = text.startsWith("a", true)
inputField?.error = if (isValid) null else "Must start with an 'a'!"
dialog.setActionButtonEnabled(POSITIVE, isValid)
}
positiveButton(R.string.submit)
}
```
# 生命周期
## 目 录
1. [Gradle 依赖](#gradle-dependency)
2. [用法](#usage)
## Gradle 依赖
[ ![Lifecycle](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/lifecycle?label=lifecycle&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/lifecycle)
`lifecycle` 模块包含一些扩展,可以使对话框与 AndroidX 生命周期一起工作。
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:lifecycle:3.2.1'
}
```
## Usage
```kotlin
MaterialDialog(this).show {
...
lifecycleOwner(owner)
}
```
当给定的生命周期所有者被销毁时,对话框将自动被解散。生命周期所有者包括来自 AndroidX 的活动和片段,以及实现 `LifecycleOwner` 接口的任何类。
# Bottom Sheets
## Table of Contents
1. [Gradle Dependency](#gradle-dependency)
2. [Usage](#usage)
3. [Layout Mode](#layout-mode)
4. [Peek Height](#peek-height)
5. [Item Grids](#item-grids)
6. [Corner Radius](#corner-radius)
---
## Gradle Dependency
[ ![Bottom Sheets](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/bottomsheets?label=bottomsheets&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/bottomsheets)
The `bottomsheets` module contains extensions to turn modal dialogs into bottom sheets, among
other functionality like showing a grid of items.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:bottomsheets:3.2.1'
}
```
## Usage
Making a dialog a bottom sheet is as simple as passing a constructed instance of `BottomSheet`
as the second parameter to `MaterialDialog`'s constructor.
```kotlin
MaterialDialog(this, BottomSheet()).show {
...
}
```
---
## Layout Mode
There are two layout modes:
* `MATCH_PARENT` - the default. The bottom sheet can be expanded to fill the height of the screen.
When opened, the bottom sheet will be at its peek height.
* `WRAP_CONTENT` - the bottom sheet can only be expanded as far as the height of the view it contains.
If the view it contains is as tall or taller than the screen, it's limited to the screen height, in
which case the content should be in a `ScrollView` as well.
The layout mode is set in the constructor of the `BottomSheet` behavior, you don't need to
explicitly set it at all if you wish to use `MATCH_PARENT`:
```kotlin
MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
...
}
```
---
## Peek Height
If you've used Android bottom sheets before, peek height should be a familiar concept. The peek
height is the height of the bottom sheet when it's not fully expanded. It's a point between
expanded and hidden.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/bottomsheet_peekheight.gif" width="250px" />
The default peek height is 60% of the screen height. You can set a custom peek height if you wish:
```kotlin
val dialog = MaterialDialog(this, BottomSheet()).show {
setPeekHeight(res = R.dimen.my_default_peek_height)
}
// You can continue to make calls to this method, and changes are still animated
dialog.setPeekHeight(res = R.dimen.another_peek_height)
```
Changes to the peek height are animated for you. If you're using the `WRAP_CONTENT` layout mode,
the peek height is limited to the max height of your bottom sheet.
---
## Item Grids
Since it's common to show a grid of items in a bottom sheet, this module contains a method to do
that.
```kotlin
val items = listOf(
BasicGridItem(R.drawable.some_icon, "One"),
BasicGridItem(R.drawable.another_icon, "Two"),
BasicGridItem(R.drawable.hello_world, "Three"),
BasicGridItem(R.drawable.material_dialogs, "Four")
)
MaterialDialog(this, BottomSheet()).show {
...
gridItems(items) { _, index, item ->
toast("Selected item ${item.title} at index $index")
}
}
```
Note that `gridItems` can take a list of anything that inherits from the `GridItem` interface,
if you wish to pass a custom item type. You just need to override the `title` value along with the
`populateIcon(ImageView)` function.
---
There a few extra parameters that you can provide, most of which are equivelent to what you can
provide to `listItems`. `customGridWidth` is an optional integer resource that allows you to set a
width for the grid - you can have different widths for different resource configurations (tablet,
landscape, etc.)
```kotlin
fun gridItems(
items: List<IT : GridItem>,
@IntegerRes customGridWidth: Int? = null,
disabledIndices: IntArray? = null,
waitForPositiveButton: Boolean = true,
selection: GridItemListener<IT> = null
): MaterialDialog
```
---
### Corner Radius
This is taken from the core module documentation. I'm reiterating it here to make sure people
know that it is possible, since it's more common to use rounding with bottom sheets than regular
modal dialogs.
Corner radius can be globally changed with an attribute in your app theme. It defaults to 4dp:
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
...
<item name="md_corner_radius">16dp</item>
</style>
```
The above effects _all_ dialogs in your app, even the normal modal ones. There is also a
programmatic setter for this value which you can use per-dialog:
```kotlin
MaterialDialog(this, BottomSheet()).show {
// literal, internally converts to dp so 16dp
cornerRadius(16f)
// Using a dimen instead is encouraged as it's easier to have all instances changeable from one place
cornerRadius(res = R.dimen.my_corner_radius)
}
```
# Color
# Table of Contents - Color
1. [Gradle Dependency](#gradle-dependency)
2. [Color Choosers](#color-choosers)
1. [Basics](#basics)
2. [Sub Colors](#sub-colors)
## Gradle Dependency
[ ![Color](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/color?label=color&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/color)
The `color` module contains extensions to the core module, such as a color chooser.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:color:3.2.1'
}
```
## Color Choosers
### Basics
Color choosers show a simple grid of colors.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/color_chooser.png" width="250px" />
```kotlin
val colors = intArrayOf(RED, GREEN, BLUE)
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(colors) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
You can specify an initial selection, which is just a color integer:
```kotlin
val colors = intArrayOf(RED, GREEN, BLUE)
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(colors, initialSelection = BLUE) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
### Sub Colors
You can specify sub-colors, which are a level down from each top level color. The size of the top
level array must match the size of the sub-colors array.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/color_chooser_sub.png" width="250px" />
```kotlin
val colors = intArrayOf(RED, GREEN, BLUE) // size = 3
val subColors = listOf( // size = 3
intArrayOf(LIGHT_RED, RED, DARK_RED, WHITE),
intArrayOf(LIGHT_GREEN, GREEN, DARK_GREEN, GRAY),
intArrayOf(LIGHT_BLUE, BLUE, DARK_BLUE, BLACK)
)
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(colors, subColors = subColors) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
### ARGB Selection
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/custom_argb.png" width="250px" />
```kotlin
MaterialDialog(this).show {
title(R.string.colors)
colorChooser(
colors = colors,
subColors = subColors,
allowCustomArgb = true,
showAlphaSelector = true
) { dialog, color ->
// Use color integer
}
positiveButton(R.string.select)
}
```
Omitting `showAlphaSelector` will hide the alpha (transparency) selector.
# Core
## Table of Contents
1. [Gradle Dependency](#gradle-dependency)
2. [Basics](#basics)
3. [Customizing the Message](#customizing-the-message)
4. [Action Buttons](#action-buttons)
5. [Adding an Icon](#adding-an-icon)
6. [Callbacks](#callbacks)
7. [Dismissing](#dismissing)
8. [Lists](#lists)
1. [Plain](#plain)
2. [Single Choice](#single-choice)
3. [Multiple Choice](#multiple-choice)
4. [Custom Adapters](#custom-adapters)
9. [Checkbox Prompts](#checkbox-prompts)
10. [Custom Views](#custom-views)
11. [Miscellaneous](#miscellaneous)
12. [Theming](#theming)
1. [Light and Dark](#light-and-dark)
2. [Background Color](#background-color)
3. [Ripple Color](#ripple-color)
4. [Corner Radius](#corner-radius)
5. [Text Color](#text-color)
6. [Fonts](#fonts)
7. [Widget Color](#widget-color)
## Gradle Dependency
[ ![Core](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/core?label=core&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/core)
The `core` module contains everything you need to get started with the library. It contains all
core and normal-use functionality.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:core:3.2.1'
}
```
## Basics
Here's a very basic example of creating and showing a dialog:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic.png" width="250px" />
```kotlin
MaterialDialog(this).show {
title(R.string.your_title)
message(R.string.your_message)
}
```
`this` should be a `Context` which is attached to a window, like an `Activity`.
If you wanted to pass in literal strings instead of string resources:
```kotlin
MaterialDialog(this).show {
title(text = "Your Title")
message(text = "Your Message")
}
```
Note that you can setup a dialog without immediately showing it, as well:
```kotlin
val dialog = MaterialDialog(this)
.title(R.string.your_title)
.message(R.string.your_message)
dialog.show()
```
## Customizing the Message
The `message` function lets you trail it with a lambda, which exposes certain built-in modifiers
along with allowing you to act on the `TextView` directly.
```kotlin
MaterialDialog(this).show {
...
message(R.string.your_message) {
html() // format, color, etc. with tags in string
html { link -> // same as above, but...
// Invokes a callback when a URL is clicked instead of auto opening it in a browser
}
lineSpacing(1.4f) // modifies line spacing, default is 1.0f
// You can directly act on the message TextView as well
val textView = messageTextView
}
}
```
## Action Buttons
There are simple methods for adding action buttons:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic_with_buttons.png" width="250px" />
```kotlin
MaterialDialog(this).show {
positiveButton(R.string.agree)
negativeButton(R.string.disagree)
}
```
You can use literal strings here as well:
```kotlin
MaterialDialog(this).show {
positiveButton(text = "Agree")
negativeButton(text = "Disagree")
}
```
---
Listening for clicks on the buttons is as simple as adding a lambda to the end:
```kotlin
MaterialDialog(this).show {
positiveButton(R.string.agree) { dialog ->
// Do something
}
negativeButton(R.string.disagree) { dialog ->
// Do something
}
}
```
If action buttons together are too long to fit in the dialog's width, they will be automatically
stacked:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/stacked_buttons.png" width="250px" />
## Adding an Icon
You can display an icon to the left of the title:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/icon.png" width="250px" />
```kotlin
MaterialDialog(this).show {
icon(R.drawable.your_icon)
}
```
You can pass a Drawable instance as well:
```kotlin
val myDrawable: Drawable = // ...
MaterialDialog(this).show {
icon(drawable = myDrawable)
}
```
## Callbacks
There are a few lifecycle callbacks you can hook into:
```kotlin
MaterialDialog(this).show {
onPreShow { dialog -> }
onShow { dialog -> }
onDismiss { dialog -> }
onCancel { dialog -> }
}
```
## Dismissing
Dismissing a dialog closes it, it's just a simple method inherited from the parent `Dialog` class:
```kotlin
val dialog: MaterialDialog = // ...
dialog.dismiss()
```
---
You can prevent a dialog from being canceled, meaning it has to be explictly dismissed with an
action button or a call to the method above.
```kotlin
MaterialDialog(this).show {
cancelable(false) // calls setCancelable on the underlying dialog
cancelOnTouchOutside(false) // calls setCanceledOnTouchOutside on the underlying dialog
}
```
## Lists
### Plain
You can show lists using the `listItems` extension on `MaterialDialog`:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic_list.png" width="250px" />
```kotlin
MaterialDialog(this).show {
listItems(R.array.socialNetworks)
}
```
You can pass a literal string array too:
```kotlin
val myItems = listOf("Hello", "World")
MaterialDialog(this).show {
listItems(items = myItems)
}
```
To get item selection events, just append a lambda:
```kotlin
MaterialDialog(this).show {
listItems(R.array.socialNetworks) { dialog, index, text ->
// Invoked when the user taps an item
}
}
```
### Single Choice
You can show single choice (radio button) lists using the `listItemsSingleChoice` extension
on `MaterialDialog`:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/single_choice_list.png" width="250px" />
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items)
}
```
You can pass a literal string array too:
```kotlin
val myItems = listOf("Hello", "World")
MaterialDialog(this).show {
listItemsSingleChoice(items = myItems)
}
```
---
If you want an option to be selected when the dialog opens, you can pass an `initialSelection` index):
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items, initialSelection = 1)
}
```
To get item selection events, just append a lambda:
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items) { dialog, index, text ->
// Invoked when the user selects an item
}
}
```
Without action buttons, the selection callback is invoked immediately when the user taps an item. If
you add a positive action button...
```kotlin
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items) { dialog, index, text ->
// Invoked when the user selects an item
}
positiveButton(R.string.select)
}
```
...then the callback isn't invoked until the user selects an item *and* taps the positive action
button. You can override that behavior using the `waitForPositiveButton` argument.
An added bonus, you can disable items from being selected/unselected:
```kotlin
val indices = intArrayOf(0, 2)
MaterialDialog(this).show {
listItemsSingleChoice(R.array.my_items, disabledIndices = indices)
}
```
---
There are methods you can use in a built dialog to modify checked states:
```kotlin
val dialog: MaterialDialog = // ...
dialog.checkItem(index)
dialog.uncheckItem(index)
dialog.toggleItemChecked(index)
val checked: Boolean = dialog.isItemChecked(index)
```
### Multiple Choice
You can show multiple choice (checkbox) lists using the `listItemsMultiChoice` extension on `MaterialDialog`:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/multi_choice_list.png" width="250px" />
```kotlin
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items) { _, index, text ->
// Invoked when the user selects item(s)
}
}
```
You can pass a literal string array too:
```kotlin
val myItems = listOf("Hello", "World")
MaterialDialog(this).show {
listItemsMultiChoice(items = myItems)
}
```
---
If you want option(s) to be selected when the dialog opens, you can pass an `initialSelection` index):
```kotlin
val indices = intArrayOf(1, 3)
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items, initialSelection = indices)
}
```
To get item selection events, just append a lambda:
```kotlin
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items) { dialog, indices, items ->
// Invoked when the user selects an item
}
}
```
Without action buttons, the selection callback is invoked immediately when the user taps an item. If
you add a positive action button...
```kotlin
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items) { dialog, indices, items ->
// Invoked when the user selects an item
}
positiveButton(R.string.select)
}
```
...then the callback isn't invoked until the user select one or more items *and* taps the positive
action button. You can override that behavior using the `waitForPositiveButton` argument.
An added bonus, you can disable items from being selected/unselected:
```kotlin
val indices = intArrayOf(0, 2)
MaterialDialog(this).show {
listItemsMultiChoice(R.array.my_items, disabledIndices = indices)
}
```
---
There are methods you can use in a built dialog to modify checked states:
```kotlin
val dialog: MaterialDialog = // ...
val indices: IntArray = // ...
dialog.checkItems(indices)
dialog.uncheckItems(indices)
dialog.toggleItemsChecked(indices)
dialog.checkAllItems()
dialog.uncheckAllItems()
dialog.toggleAllItemsChecked()
val checked: Boolean = dialog.isItemChecked(index)
```
### Custom Adapters
If you want to customize lists to use your own views, you need to use a custom adapter.
```kotlin
val adapter: RecyclerView.Adapter<*> = // some sort of adapter implementation...
MaterialDialog(this).show {
customListAdapter(adapter)
}
```
You can retrieve your adapter again later from the dialog instance:
```kotlin
val dialog: MaterialDialog = // ...
val adapter: RecyclerView.Adapter<*> = dialog.getListAdapter()
```
You can also retrieve the `RecyclerView` that the adapter is hosted in:
```kotlin
val dialog: MaterialDialog = // ...
val recyclerView: RecyclerView = dialog.getRecyclerView()
```
## Checkbox Prompts
Checkbox prompts can be used together with any other dialog type, it gets shown in the same view
which shows the action buttons.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/checkbox_prompt.png" width="250px" />
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(R.string.your_label) { checked ->
// Check box was checked or unchecked
}
}
```
You can pass a literal string for the label too:
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(text = "Hello, World")
}
```
---
You can also append a lambda which gets invoked when the checkbox is checked or unchecked:
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(text = "Hello, World") { checked -> }
}
```
If you only care about the checkbox state when the positive action button is pressed:
```kotlin
MaterialDialog(this).show {
checkBoxPrompt(R.string.your_label)
positiveButton(R.string.button_text) { dialog ->
val isChecked = dialog.isCheckPromptChecked()
// do something
}
}
```
## Custom Views
A lot of the included extensions use custom views, such as the color chooser dialog. There's also
a simple example in the sample project.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/custom_view.png" width="250px" />
```kotlin
MaterialDialog(this).show {
customView(R.layout.my_custom_view)
}
```
You can also pass a literal view:
```kotlin
val myView: View = // ...
MaterialDialog(this).show {
customView(view = myView)
}
```
If your custom view may be taller than the dialog, you'll want to make it scrollable:
```kotlin
MaterialDialog(this).show {
customView(R.layout.my_custom_view, scrollable = true)
}
```
For later access, you can use `dialog.getCustomView()`:
```kotlin
val dialog = MaterialDialog(this)
.customView(R.layout.my_custom_view, scrollable = true)
val customView = dialog.getCustomView()
// Use the view instance, e.g. to set values or setup listeners
dialog.show()
```
## Miscellaneous
There are little details which are easy to miss. For an example, auto dismiss controls whether pressing
the action buttons or tapping a list item will automatically dismiss the dialog or not. By default,
it's turned on. You can disable it:
```kotlin
MaterialDialog(this).show {
noAutoDismiss()
}
```
## Theming
Google's newer mindset with Material Theming (vs the 2014 mindset) is flexible. If you take their
["Crane example"](https://material.io/design/components/dialogs.html#theming), you see that they
change fonts, corner rounding, etc.
### Light and Dark
Light and dark theming is automatic based on your app's theme (basically whether `android:textColorPrimary`
is more light or more dark):
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/lightanddarkthemes.png" width="500px" />
### Background Color
Material Dialogs uses the value of the `colorBackgroundFloating` attribute in your Activity theme
for the background color of dialogs. You can also use the `md_background_color` attribute in your
theme, which will take precedence.
### Ripple Color
Material Dialogs uses the value of the `?android:colorControlHighlight` attribute in your Activity
theme for the ripple color of list items, buttons, etc. by default. You can override this with the
`md_ripple_color` theme attribute as well.
### Corner Radius
Corner radius is the rounding of dialog corners:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/customtheme.png" width="250px" />
it can be changed with an attribute in your app theme. It defaults to 4dp:
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
<item name="md_corner_radius">16dp</item>
</style>
```
There is also a programmatic setter for this value:
```kotlin
MaterialDialog(this).show {
// literal, internally converts to dp so 16dp
cornerRadius(16f)
// Using a dimen instead is encouraged as it's easier to have all instances changeable from one place
cornerRadius(res = R.dimen.my_corner_radius)
}
```
### Text Color
By default, `android:textColorPrimary` and `android:textColorSecondary` attributes from your Activity
theme are used for the title and content colors of dialogs. `colorPrimary` is used for the default
text color of action buttons. If you wish to override these, there are attributes provided:
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
<item name="md_color_title">@color/your_color</item>
<item name="md_color_content">@color/your_color</item>
<item name="md_color_button_text">@color/your/color</item>
</style>
```
### Fonts
This library supports using custom fonts, powered by the Support libraries `ResourcesCompat` class.
With raw font files or XML font files in your `/res/font` folder, you can use them in Material Dialogs
using attributes in your app's theme.
```xml
<style name="AppTheme.Custom" parent="Theme.AppCompat">
<item name="md_font_title">@font/your_font</item>
<item name="md_font_body">@font/your_font</item>
<item name="md_font_button">@font/your_font</item>
</style>
```
See the "Custom Theme" example in the sample project (open the overflow menu for the theme switcher).
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/customtheme.png" width="250px" />
# DateTime
## Table of Contents
1. [Gradle Dependency](#gradle-dependency-4)
2. [Date](#date)
3. [Time](#time)
4. [DateTime](#datetime)
## Gradle Dependency
[ ![DateTime](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/datetime?label=datetime&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/datetime)
The `datetime` module contains extensions to make date, time, and date-time picker dialogs.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:datetime:3.2.1'
}
```
## Date
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/datepicker.png" width="250px" />
```kotlin
MaterialDialog(this).show {
...
datePicker { dialog, date ->
// Use date (Calendar)
}
}
```
You can optionally provide `minDate`, `maxDate` and `currentDate` parameters as well.
## Time
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/timepicker.png" width="250px" />
```kotlin
MaterialDialog(this).show {
...
timePicker { dialog, time ->
// Use time (Calendar)
}
}
```
You can optionally provide `currentTime` and `show24HoursView` parameters as well.
## DateTime
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/datetimepicker.png" width="400px" />
```kotlin
MaterialDialog(this).show {
...
dateTimePicker(requireFutureDateTime = true) { _, dateTime ->
// Use dateTime (Calendar)
}
}
```
You can optionally provide `minDateTime`, `maxDate`, `currentDateTime`, `show24HoursView`,
and `requireFutureDateTime` parameters as well.
# Files
## Table of Contents
1. [Gradle Dependency](#gradle-dependency)
2. [File Choosers](#file-choosers)
1. [Basics](#basics)
2. [Filter](#filter)
3. [Empty Text](#empty-text)
4. [Folder Creation](#folder-creation)
3. [Folder Choosers](#folder-choosers)
1. [Basics](#basics-1)
2. [Filter](#filter-1)
3. [Empty Text](#empty-text-1)
4. [Folder Creation](#folder-creation-1)
## Gradle Dependency
[ ![Files](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/files?label=files&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/files)
The `files` module contains extensions to the core module, such as a file and folder chooser.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:files:3.2.1'
}
```
## File Choosers
### Basics
**Note:** File choosers require your app to have permission to `READ_EXTERNAL_STORAGE`, otherwise
directory listings will come back empty.
You create file choosers using the `fileChooser` extension on `MaterialDialog`:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_chooser.png" width="250px" />
```kotlin
MaterialDialog(this).show {
fileChooser { dialog, file ->
// File selected
}
}
```
It shows all files and folders, starting in the external storage directory. Tapping a file invokes
the callback and dismisses the dialog.
You can change the directory which is listed initially:
```kotlin
val initialFolder = File(getExternalStorageDirectory(), "Download")
MaterialDialog(this).show {
fileChooser(initialDirectory = initialFolder) { dialog, file ->
// File selected
}
}
```
**If a positive action button exists, tapping a file will select it, but the callback isn't invoked
until the positive action button is pressed.**
### Filter
A filter can be applied to only show the files and directories you wish to show:
```kotlin
// show ALL folders, and files that start with the letter 'a'
val myFilter: FileFilter = { it.isDirectory || it.nameWithoutExtension.startsWith("a", true) }
MaterialDialog(this).show {
fileChooser(filter = myFilter) { dialog, file ->
// File selected
}
}
```
### Empty Text
Empty text is shown when a folder has no contents. You can configure the empty text label:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_emptytext.png" width="250px" />
```kotlin
MaterialDialog(this).show {
fileChooser(emptyTextRes = R.string.custom_label) { dialog, file ->
// File selected
}
}
```
### Folder Creation
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_folder_creation.png" width="250px" />
You can allow your users to create folders.
```kotlin
MaterialDialog(this).show {
fileChooser(
allowFolderCreation = true,
folderCreationLabel = R.string.new_folder // optional as well
) { dialog, file ->
// File selected
}
}
```
This "New Folder" option is only show in directories which are writable.
## Folder Choosers
**Note:** Folder choosers require your app to have permission to `READ_EXTERNAL_STORAGE`, otherwise
directory listings will come back empty.
Folder choosers are basically the same as file choosers, with a few minor differences: 1) only folders
are shown, even when a custom filter is applied. 2) the selection callback is never invoked on a
item click, it only gets invoked with the currently viewed folder when the positive action button
is pressed.
### Basics
```kotlin
MaterialDialog(this).show {
folderChooser { dialog, folder ->
// Folder selected
}
}
```
### Filter
You can apply a filter like you can with the file chooser.
```kotlin
// show only folders that start with the letter 'a'
val myFilter: FileFilter = { it.name.startsWith("a", true) }
MaterialDialog(this).show {
folderChooser(filter = myFilter) { dialog, file ->
// Folder selected
}
}
```
### Empty Text
Empty text is shown when a folder has no contents. You can configure the empty text label:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_emptytext.png" width="250px" />
```kotlin
MaterialDialog(this).show {
folderChooser(emptyTextRes = R.string.custom_label) { dialog, file ->
// File selected
}
}
```
### Folder Creation
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_folder_creation.png" width="250px" />
You can allow your users to create folders.
```kotlin
MaterialDialog(this).show {
folderChooser(
allowFolderCreation = true,
folderCreationLabel = R.string.new_folder // optional as well
) { dialog, file ->
// File selected
}
}
```
This "New Folder" option is only show in directories which are writable.
# Input
## Table of Contents
1. [Gradle Dependency](#gradle-dependency)
2. [Text Input](#text-input)
1. [Basics](#basics)
2. [Hints and Prefill](#hints-and-prefill)
3. [Input Types](#input-types)
4. [Max Length](#max-length)
5. [Custom Validation](#custom-validation)
## Gradle Dependency
[ ![Input](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/input?label=input&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/input)
The `input` module contains extensions to the core module, such as a text input dialog.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:input:3.3.0'
}
```
## Text Input
### Basics
You can setup an input dialog using the `input` extension on `MaterialDialog`:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/input.png" width="250px" />
```kotlin
MaterialDialog(this).show {
input()
positiveButton(R.string.submit)
}
```
With a setup input dialog, you can retrieve the input field:
```kotlin
val dialog: MaterialDialog = // ...
val inputField: EditText = dialog.getInputField()
```
---
You can append a lambda to receive a callback when the positive action button is pressed with
text entered:
```kotlin
MaterialDialog(this).show {
input { dialog, text ->
// Text submitted with the action button
}
positiveButton(R.string.submit)
}
```
If you set `waitForPositiveButton` to false, the callback is invoked every time the text field is
modified:
```kotlin
MaterialDialog(this).show {
input(waitForPositiveButton = false) { dialog, text ->
// Text changed
}
positiveButton(R.string.done)
}
```
To allow the positive action button to be pressed even when the input is empty:
```kotlin
MaterialDialog(this).show {
input(allowEmpty = true) { dialog, text ->
// Text submitted with the action button, might be an empty string`
}
positiveButton(R.string.done)
}
```
### Hints and Prefill
You can set a hint to the input field, which is the gray faded text shown when the field is empty:
```kotlin
MaterialDialog(this).show {
input(hintRes = R.string.hint_text)
}
```
A literal string can be used as well:
```kotlin
MaterialDialog(this).show {
input(hint = "Your Hint Text")
}
```
---
You can also prefill the input field:
```kotlin
MaterialDialog(this).show {
input(prefillRes = R.string.prefill_text)
}
```
A literal string can be used as well:
```kotlin
MaterialDialog(this).show {
input(prefill = "Prefilled text")
}
```
### Input Types
You can apply input types to the input field, which modifies the keyboard type when the field is
focused on. This is just taken right from the Android framework, the input type gets applied
directly to the underlying `EditText`:
```kotlin
val type = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
MaterialDialog(this).show {
input(inputType = type)
}
```
### Max Length
You can set a max length which makes a character counter visible, and disables the positive action
button if the input length goes over that:
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/input_max_length.png" width="250px" />
```kotlin
MaterialDialog(this).show {
input(maxLength = 8)
positiveButton(R.string.submit)
}
```
### Custom Validation
You can do custom validation using the input listener. This example enforces that the input
starts with the letter 'a':
```kotlin
MaterialDialog(this).show {
input(waitForPositiveButton = false) { dialog, text ->
val inputField = dialog.getInputField()
val isValid = text.startsWith("a", true)
inputField?.error = if (isValid) null else "Must start with an 'a'!"
dialog.setActionButtonEnabled(POSITIVE, isValid)
}
positiveButton(R.string.submit)
}
```
# Lifecycle
## Table of Contents
1. [Gradle Dependency](#gradle-dependency)
2. [Usage](#usage)
## Gradle Dependency
[ ![Lifecycle](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/lifecycle?label=lifecycle&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/lifecycle)
The `lifecycle` module contains extensions to make dialogs work with AndroidX lifecycles.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:lifecycle:3.2.1'
}
```
## Usage
```kotlin
MaterialDialog(this).show {
...
lifecycleOwner(owner)
}
```
When the given lifecycle owner is destroyed, the dialog is automatically dismissed. Lifecycle
owners include Activities and Fragments from AndroidX, along with any class that implements the
`LifecycleOwner` interface.
# Material Dialogs
#### [View Releases and Changelogs](https://github.com/afollestad/material-dialogs/releases)
[![Android CI](https://github.com/afollestad/material-dialogs/workflows/Android%20CI/badge.svg)](https://github.com/afollestad/material-dialogs/actions?query=workflow%3A%22Android+CI%22)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a4acc30a9ce440087f7688735359bb8)](https://www.codacy.com/app/drummeraidan_50/material-dialogs?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=afollestad/material-dialogs&amp;utm_campaign=Badge_Grade)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
---
![Showcase](https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/showcase4.png)
# Modules
The core module is the fundamental module that you need in order to use this library. The others
are extensions to core.
Please note that since Material Dialogs 2.x.x, this library only supports Kotlin. The latest Java version is `0.9.6.0` and can be found [here](README_OLD.md). Note that 0.9.6.0 is unsupported, bugs & improvements will not be made to that version.
## Core
[ ![Core](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/core?label=core&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/core)
#### [Core Tutorial and Samples](documentation/CORE.md)
The `core` module contains everything you need to get started with the library. It contains all
core and normal-use functionality.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/basic_with_buttons.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:core:3.3.0'
}
```
## Input
[ ![Input](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/input?label=input&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/input)
#### [Input Tutorial and Samples](documentation/INPUT.md)
The `input` module contains extensions to the core module, such as a text input dialog.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/input.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:input:3.3.0'
}
```
## Files
[ ![Files](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/files?label=files&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/files)
#### [Files Tutorial and Samples](documentation/FILES.md)
The `files` module contains extensions to the core module, such as a file and folder chooser.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/file_chooser.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:files:3.3.0'
}
```
## Color
[ ![Color](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/color?label=color&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/color)
#### [Color Tutorial and Samples](documentation/COLOR.md)
The `color` module contains extensions to the core module, such as a color chooser.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/color_chooser.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:color:3.3.0'
}
```
## DateTime
[ ![DateTime](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/datetime?label=datetime&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/datetime)
#### [DateTime Tutorial and Samples](documentation/DATETIME.md)
The `datetime` module contains extensions to make date, time, and date-time picker dialogs.
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/datetimepicker.png" width="500px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:datetime:3.3.0'
}
```
## Bottom Sheets
[ ![Bottom Sheets](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/bottomsheets?label=bottomsheets&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/bottomsheets)
#### [Bottom Sheets Tutorial and Samples](documentation/BOTTOMSHEETS.md)
The `bottomsheets` module contains extensions to turn modal dialogs into bottom sheets, among
other functionality like showing a grid of items. Be sure to checkout the sample project for this,
too!
<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/main/art/bottomsheet_customview.png" width="250px" />
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
}
```
## Lifecycle
[ ![Lifecycle](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/lifecycle?label=lifecycle&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/lifecycle)
#### [Lifecycle Tutorial and Samples](documentation/LIFECYCLE.md)
The `lifecycle` module contains extensions to make dialogs work with AndroidX lifecycles.
```gradle
dependencies {
...
implementation 'com.afollestad.material-dialogs:lifecycle:3.3.0'
}
```
# Material Dialogs (Pre version 2.0, deprecated)
[ ![Core](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/core?label=core&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/core)
[ ![Commons](https://img.shields.io/maven-central/v/com.afollestad.material-dialogs/commons?label=commons&style=for-the-badge) ](https://repo1.maven.org/maven2/com/afollestad/material-dialogs/commons)
[![Build Status](https://travis-ci.org/afollestad/material-dialogs.svg)](https://travis-ci.org/afollestad/material-dialogs)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a4acc30a9ce440087f7688735359bb8)](https://www.codacy.com/app/drummeraidan_50/material-dialogs?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=afollestad/material-dialogs&amp;utm_campaign=Badge_Grade)
[![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/afollestad/material-dialogs/blob/master/LICENSE.txt)
![Screenshots](https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/readmeshowcase.png)
# Table of Contents (Core)
1. [Sample Project](https://github.com/afollestad/material-dialogs#sample-project)
2. [Gradle Dependency](https://github.com/afollestad/material-dialogs#gradle-dependency)
1. [Repository](https://github.com/afollestad/material-dialogs#repository)
2. [Core](https://github.com/afollestad/material-dialogs#core)
3. [Commons](https://github.com/afollestad/material-dialogs#commons)
3. [What's New](https://github.com/afollestad/material-dialogs#whats-new)
4. [Basic Dialog](https://github.com/afollestad/material-dialogs#basic-dialog)
5. [Dismissing Dialogs](https://github.com/afollestad/material-dialogs#dismissing-dialogs)
6. [Displaying an Icon](https://github.com/afollestad/material-dialogs#displaying-an-icon)
7. [Stacked Action Buttons](https://github.com/afollestad/material-dialogs#stacked-action-buttons)
1. [Stacking Behavior](https://github.com/afollestad/material-dialogs#stacking-behavior)
8. [Neutral Action Button](https://github.com/afollestad/material-dialogs#neutral-action-button)
9. [Callbacks](https://github.com/afollestad/material-dialogs#callbacks)
10. [CheckBox Prompts](https://github.com/afollestad/material-dialogs#checkbox-prompts)
11. [List Dialogs](https://github.com/afollestad/material-dialogs#list-dialogs)
12. [Single Choice List Dialogs](https://github.com/afollestad/material-dialogs#single-choice-list-dialogs)
1. [Coloring Radio Buttons](https://github.com/afollestad/material-dialogs#coloring-radio-buttons)
13. [Multi Choice List Dialogs](https://github.com/afollestad/material-dialogs#multi-choice-list-dialogs)
1. [Coloring Check Boxes](https://github.com/afollestad/material-dialogs#coloring-check-boxes)
14. [Assigning IDs to List Item Views](https://github.com/afollestad/material-dialogs#assigning-ids-to-list-item-views)
15. [Custom List Dialogs](https://github.com/afollestad/material-dialogs#custom-list-dialogs)
16. [Custom Views](https://github.com/afollestad/material-dialogs#custom-views)
1. [Later Access](https://github.com/afollestad/material-dialogs#later-access)
17. [Typefaces](https://github.com/afollestad/material-dialogs#typefaces)
18. [Getting and Setting Action Buttons](https://github.com/afollestad/material-dialogs#getting-and-setting-action-buttons)
19. [Theming](https://github.com/afollestad/material-dialogs#theming)
1. [Basics](https://github.com/afollestad/material-dialogs#basics)
2. [Colors](https://github.com/afollestad/material-dialogs#colors)
3. [Selectors](https://github.com/afollestad/material-dialogs#selectors)
4. [Gravity](https://github.com/afollestad/material-dialogs#gravity)
5. [Material Palette](https://github.com/afollestad/material-dialogs#material-palette)
20. [Global Theming](https://github.com/afollestad/material-dialogs#global-theming)
21. [Show, Cancel, and Dismiss Callbacks](https://github.com/afollestad/material-dialogs#show-cancel-and-dismiss-callbacks)
22. [Input Dialogs](https://github.com/afollestad/material-dialogs#input-dialogs)
1. [Coloring the EditText](https://github.com/afollestad/material-dialogs#coloring-the-edittext)
2. [Limiting Input Length](https://github.com/afollestad/material-dialogs#limiting-input-length)
3. [Custom Invalidation](https://github.com/afollestad/material-dialogs#custom-invalidation)
23. [Progress Dialogs](https://github.com/afollestad/material-dialogs#progress-dialogs)
1. [Proguard](https://github.com/afollestad/material-dialogs#proguard)
2. [Indeterminate Progress Dialogs](https://github.com/afollestad/material-dialogs#indeterminate-progress-dialogs)
3. [Determinate (Seek Bar) Progress Dialogs](https://github.com/afollestad/material-dialogs#determinate-seek-bar-progress-dialogs)
4. [Make an Indeterminate Dialog Horizontal](https://github.com/afollestad/material-dialogs#make-an-indeterminate-dialog-horizontal)
5. [Coloring the Progress Bar](https://github.com/afollestad/material-dialogs#coloring-the-progress-bar)
6. [Custom Number and Progress Formats](https://github.com/afollestad/material-dialogs#custom-number-and-progress-formats)
24. [Tint Helper](https://github.com/afollestad/material-dialogs#tint-helper)
25. [Misc](https://github.com/afollestad/material-dialogs#misc)
# Table of Contents (Commons)
1. [Color Chooser Dialogs](https://github.com/afollestad/material-dialogs#color-chooser-dialogs)
1. [Finding Visible Dialogs](https://github.com/afollestad/material-dialogs#finding-visible-dialogs)
2. [User Color Input](https://github.com/afollestad/material-dialogs#user-color-input)
2. [File Selector Dialogs](https://github.com/afollestad/material-dialogs#file-selector-dialogs)
3. [Folder Selector Dialogs](https://github.com/afollestad/material-dialogs#folder-selector-dialogs)
4. [Preference Dialogs](https://github.com/afollestad/material-dialogs#preference-dialogs)
5. [Simple List Dialogs](https://github.com/afollestad/material-dialogs#simple-list-dialogs)
------
# Sample Project
You can download the latest sample APK from this repo here: https://github.com/afollestad/material-dialogs/blob/master/sample/sample.apk
It's also on Google Play:
<a href="https://play.google.com/store/apps/details?id=com.afollestad.materialdialogssample" target="_blank">
<img alt="Get it on Google Play"
src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" height="60"/>
</a>
Having the sample project installed is a good way to be notified of new releases. Although Watching this
repository will allow GitHub to email you whenever I publish a release.
---
# Gradle Dependency
### Repository
The Gradle dependency is available via [jCenter](https://bintray.com/drummer-aidan/maven/material-dialogs:core/view).
jCenter is the default Maven repository used by Android Studio.
The minimum API level supported by this library is API 14.
### Core
The *core* module contains all the major classes of this library, including `MaterialDialog`.
You can create basic, list, single/multi choice, progress, input, etc. dialogs with core.
```gradle
dependencies {
// ... other dependencies here
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
}
```
### Commons
The *commons* module contains extensions to the library that not everyone may need. This includes the
`ColorChooserDialog`, `FolderChooserDialog`, the Material `Preference` classes, and `MaterialSimpleListAdapter`/`MaterialSimpleListItem`.
```gradle
dependencies {
// ... other dependencies here
implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
}
```
It's likely that new extensions will be added to commons later.
---
# What's New
See the project's Releases page for a list of versions with their changelogs.
### [View Releases](https://github.com/afollestad/material-dialogs/releases)
If you Watch this repository, GitHub will send you an email every time I publish an update.
---
# Basic Dialog
First of all, note that `MaterialDialog` extends `DialogBase`, which extends `android.app.Dialog`.
Here's a basic example that mimics the dialog you see on Google's Material design guidelines
(here: http://www.google.com/design/spec/components/dialogs.html#dialogs-usage). Note that you can
always substitute literal strings and string resources for methods that take strings, the same goes
for color resources (e.g. `titleColor` and `titleColorRes`).
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.negativeText(R.string.disagree)
.show();
```
**Your Activities need to inherit the AppCompat themes in order to work correctly with this library.**
The Material dialog will automatically match the `positiveColor` (which is used on the positive action
button) to the `colorAccent` attribute of your styles.xml theme.
If the content is long enough, it will become scrollable and a divider will be displayed above the action buttons.
---
# Dismissing Dialogs
I've had lots of issues asking how you dismiss a dialog. It works the same way that `AlertDialog` does, as
both `AlertDialog` and `MaterialDialog` are an instance of `android.app.Dialog` (which is where `dismiss()`
and `show()` come from). You cannot dismiss a dialog using it's `Builder`. You can only dismiss a
dialog using the dialog itself.
There's many ways you can get an instance of `MaterialDialog`. The two major ways are through the `show()` and `build()`
methods of `MaterialDialog.Builder`.
Through `show()`, which immediately shows the dialog and returns the visible dialog:
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.show();
```
Through `build()`, which only builds the dialog but doesn't show it until you say so:
```java
MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree);
MaterialDialog dialog = builder.build();
dialog.show();
```
Once the dialog is shown, you can dismiss it:
```java
dialog.dismiss();
```
There are other various places where the `MaterialDialog` instance is given, such as in some callbacks
that are discussed in future sections below.
---
# Displaying an Icon
MaterialDialog supports the display of an icon just like the stock AlertDialog; it will go to the left of the title.
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.icon(R.drawable.icon)
.show();
```
You can limit the maximum size of the icon using the `limitIconToDefaultSize()`, `maxIconSize(int size)`,
or `maxIconSizeRes(int sizeRes)` Builder methods.
---
# Stacked Action Buttons
If you have multiple action buttons that together are too wide to fit on one line, the dialog will stack the
buttons to be vertically oriented.
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.longer_positive)
.negativeText(R.string.negative)
.show();
```
### Stacking Behavior
You can set stacking behavior from the `Builder`:
```java
new MaterialDialog.Builder(this)
...
.stackingBehavior(StackingBehavior.ADAPTIVE) // the default value
.show();
```
---
# Neutral Action Button
You can specify neutral text in addition to the positive and negative text. It will show the neutral
action on the far left.
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.content(R.string.content)
.positiveText(R.string.agree)
.negativeText(R.string.disagree)
.neutralText(R.string.more_info)
.show();
```
---
# Callbacks
**As of version 0.8.2.0, the `callback()` Builder method is deprecated in favor of the individual callback methods
discussed below. Earlier versions will still require use of `ButtonCallback`.**
To know when the user selects an action button, you set callbacks:
```java
new MaterialDialog.Builder(this)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
})
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
})
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
// TODO
}
});
```
If you are listening for all three action buttons, you could just use `onAny()`. The `which` (`DialogAction`)
parameter will tell you which button was pressed.
If `autoDismiss` is turned off, then you must manually dismiss the dialog in these callbacks. Auto dismiss is on by default.
---
# CheckBox Prompts
Checkbox prompts allow you to display a UI similar to what Android uses to ask for a permission on API 23+.
**Note:** you can use checkbox prompts with list dialogs and input dialogs, too.
```java
new MaterialDialog.Builder(this)
.iconRes(R.drawable.ic_launcher)
.limitIconToDefaultSize()
.title(R.string.example_title)
.positiveText(R.string.allow)
.negativeText(R.string.deny)
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
showToast("Prompt checked? " + dialog.isPromptCheckBoxChecked());
}
})
.checkBoxPromptRes(R.string.dont_ask_again, false, null)
.show();
```
---
# List Dialogs
Creating a list dialog only requires passing in an array of strings. The callback (`itemsCallback`) is
also very simple.
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.items(R.array.items)
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
}
})
.show();
```
If `autoDismiss` is turned off, then you must manually dismiss the dialog in the callback. Auto dismiss is on by default.
You can pass `positiveText()` or the other action buttons to the builder to force it to display the action buttons
below your list, however this is only useful in some specific cases.
---
# Single Choice List Dialogs
Single choice list dialogs are almost identical to regular list dialogs. The only difference is that
you use `itemsCallbackSingleChoice` to set a callback rather than `itemsCallback`. That signals the dialog to
display radio buttons next to list items.
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.items(R.array.items)
.itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
/**
* If you use alwaysCallSingleChoiceCallback(), which is discussed below,
* returning false here won't allow the newly selected radio button to actually be selected.
**/
return true;
}
})
.positiveText(R.string.choose)
.show();
```
If you want to preselect an item, pass an index 0 or greater in place of -1 in `itemsCallbackSingleChoice()`.
Later, you can update the selected index using `setSelectedIndex(int)` on the `MaterialDialog` instance,
if you're not using a custom adapter.
If you do not set a positive action button using `positiveText()`, the dialog will automatically call
the single choice callback when user presses the positive action button. The dialog will also dismiss itself,
unless auto dismiss is turned off.
If you make a call to `alwaysCallSingleChoiceCallback()`, the single choice callback will be called
every time the user selects/unselects an item.
## Coloring Radio Buttons
Like action buttons and many other elements of the Material dialog, you can customize the color of a
dialog's radio buttons. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
`widgetColorAttr()`, and `choiceWidgetColor()` method. Their names and parameter annotations make them self explanatory.
`widgetColor` is the same color that affects other UI elements. `choiceWidgetColor` is specific to
single and multiple choice dialogs, it only affects radio buttons and checkboxes. You provide a
`ColorStateList` rather than a single color which is used to generate a `ColorStateList`.
Note that by default, radio buttons will be colored with the color held in `colorAccent` (for AppCompat)
or `android:colorAccent` (for the Material theme) in your Activity's theme.
There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
---
# Multi Choice List Dialogs
Multiple choice list dialogs are almost identical to regular list dialogs. The only difference is that
you use `itemsCallbackMultiChoice` to set a callback rather than `itemsCallback`. That signals the dialog to
display check boxes next to list items, and the callback can return multiple selections.
```java
new MaterialDialog.Builder(this)
.title(R.string.title)
.items(R.array.items)
.itemsCallbackMultiChoice(null, new MaterialDialog.ListCallbackMultiChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text) {
/**
* If you use alwaysCallMultiChoiceCallback(), which is discussed below,
* returning false here won't allow the newly selected check box to actually be selected
* (or the newly unselected check box to be unchecked).
* See the limited multi choice dialog example in the sample project for details.
**/
return true;
}
})
.positiveText(R.string.choose)
.show();
```
If you want to preselect any items, pass an array of indices (resource or literal) in place of null
in `itemsCallbackMultiChoice()`. Later, you can update the selected indices using `setSelectedIndices(Integer[])`
on the `MaterialDialog` instance, if you're not using a custom adapter.
If you do not set a positive action button using `positiveText()`, the dialog will automatically call
the multi choice callback when user presses the positive action button. The dialog will also dismiss itself,
unless auto dismiss is turned off.
If you make a call to `alwaysCallMultiChoiceCallback()`, the multi choice callback will be called
every time the user selects/unselects an item.
## Coloring Check Boxes
Like action buttons and many other elements of the Material dialog, you can customize the color of a
dialog's check boxes. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
`widgetColorAttr()`, and `choiceWidgetColor()` method. Their names and parameter annotations make them self explanatory.
`widgetColor` is the same color that affects other UI elements. `choiceWidgetColor` is specific to
single and multiple choice dialogs, it only affects radio buttons and checkboxes. You provide a
`ColorStateList` rather than a single color which is used to generate a `ColorStateList`.
Note that by default, radio buttons will be colored with the color held in `colorAccent` (for AppCompat)
or `android:colorAccent` (for the Material theme) in your Activity's theme.
There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
---
# Assigning IDs to List Item Views
If you need to keep track of list items by ID rather than index, you can assign item IDs from an integer array:
```java
new MaterialDialog.Builder(this)
.title(R.string.socialNetworks)
.items(R.array.socialNetworks)
.itemsIds(R.array.itemIds)
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
Toast.makeText(Activity.this, which + ": " + text + ", ID = " + view.getId(), Toast.LENGTH_SHORT).show();
}
})
.show();
```
You can also pass a literal integer array (`int[]`) in place of an array resource ID.
---
# Custom List Dialogs
Like Android's native dialogs, you can also pass in your own adapter via `.adapter()` to customize
exactly how you want your list to work.
```java
new MaterialDialog.Builder(this)
.title(R.string.socialNetworks)
// second parameter is an optional layout manager. Must be a LinearLayoutManager or GridLayoutManager.
.adapter(new ButtonItemAdapter(this, R.array.socialNetworks), null)
.show();
```
**Note** that with newer releases, Material Dialogs no longer supports `ListView` and `ListAdapter`.
It's about time that everyone uses `RecyclerView`. **Your custom adapters will have to handle item click
events on their own; this library's classes and sample project have some good examples of how that is done correctly.**
If you need access to the `RecyclerView`, you can use the `MaterialDialog` instance:
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
...
.build();
RecyclerView list = dialog.getRecyclerView();
// Do something with it
dialog.show();
```
Note that you don't need to be using a custom adapter in order to access the `RecyclerView`, it's there for single/multi choice dialogs, regular list dialogs, etc.
---
# Custom Views
Custom views are very easy to implement.
```java
boolean wrapInScrollView = true;
new MaterialDialog.Builder(this)
.title(R.string.title)
.customView(R.layout.custom_view, wrapInScrollView)
.positiveText(R.string.positive)
.show();
```
If `wrapInScrollView` is true, then the library will place your custom view inside of a ScrollView for you.
This allows users to scroll your custom view if necessary (small screens, long content, etc.). However, there are cases
when you don't want that behavior. This mostly consists of cases when you'd have a ScrollView in your custom layout,
including ListViews, RecyclerViews, WebViews, GridViews, etc. The sample project contains examples of using both true
and false for this parameter.
Your custom view will automatically have padding put around it when `wrapInScrollView` is true. Otherwise
you're responsible for using padding values that look good with your content.
## Later Access
If you need to access a View in the custom view after the dialog is built, you can use `getCustomView()` of
`MaterialDialog`. This is especially useful if you pass a layout resource to the `Builder`, the dialog will
handle the view inflation for you.
```java
MaterialDialog dialog = //... initialization via the builder ...
View view = dialog.getCustomView();
```
---
# Typefaces
If you want to use custom fonts, you can make a call to `typeface(String, String)` when
using the `Builder`. This will pull fonts from files in your project's `assets/fonts` folder. For example,
if you had `Roboto.ttf` and `Roboto-Light.ttf` in `/src/main/assets/fonts`, you would call `typeface("Roboto.ttf", "Roboto-Light.ttf")`.
This method will also handle recycling Typefaces via the `TypefaceHelper` which you can use in your own project to avoid duplicate
allocations. The raw `typeface(Typeface, Typeface)` variation will not recycle typefaces, every call will allocate the Typeface again.
There's a global theming attribute available to automatically apply fonts to every Material Dialog in
your app, also.
---
# Getting and Setting Action Buttons
If you want to get a reference to one of the dialog action buttons after the dialog is built and shown (e.g. to enable or disable buttons):
```java
MaterialDialog dialog = //... initialization via the builder ...
View negative = dialog.getActionButton(DialogAction.NEGATIVE);
View neutral = dialog.getActionButton(DialogAction.NEUTRAL);
View positive = dialog.getActionButton(DialogAction.POSITIVE);
```
If you want to update the title of a dialog action button (you can pass a string resource ID in place of the literal string, too):
```java
MaterialDialog dialog = //... initialization via the builder ...
dialog.setActionButton(DialogAction.NEGATIVE, "New Title");
```
---
# Theming
Before Lollipop, theming AlertDialogs was basically impossible without using reflection and custom drawables.
Since KitKat, Android became more color neutral but AlertDialogs continued to use Holo Blue for the title and
title divider. Lollipop has improved even more, with no colors in the dialog by default other than the action
buttons. This library makes theming even easier.
## Basics
By default, Material Dialogs will apply a light theme or dark theme based on the `?android:textColorPrimary`
attribute retrieved from the context creating the dialog. If the color is light (e.g. more white), it will
guess the Activity is using a dark theme and it will use the dialog's dark theme. Vice versa for the light theme.
You can manually set the theme used from the `Builder#theme()` method:
```java
new MaterialDialog.Builder(this)
.content("Hi")
.theme(Theme.DARK)
.show();
```
Or you can use the global theming attribute, which is discussed in the section below. Global theming
avoids having to constantly call theme setters for every dialog you show.
## Colors
Pretty much every aspect of a dialog created with this library can be colored:
```java
new MaterialDialog.Builder(this)
.titleColorRes(R.color.material_red_500)
.contentColor(Color.WHITE) // notice no 'res' postfix for literal color
.linkColorAttr(R.attr.my_link_color_attr) // notice attr is used instead of none or res for attribute resolving
.dividerColorRes(R.color.material_pink_500)
.backgroundColorRes(R.color.material_blue_grey_800)
.positiveColorRes(R.color.material_red_500)
.neutralColorRes(R.color.material_red_500)
.negativeColorRes(R.color.material_red_500)
.widgetColorRes(R.color.material_red_500)
.buttonRippleColorRes(R.color.material_red_500)
.show();
```
The names are self explanatory for the most part. The `widgetColor` method, discussed in a few other
sections of this tutorial, applies to progress bars, check boxes, and radio buttons. Also note that
each of these methods have 3 variations for setting a color directly, using color resources, and using
color attributes.
## Selectors
Selectors are drawables that change state when pressed or focused.
```java
new MaterialDialog.Builder(this)
.btnSelector(R.drawable.custom_btn_selector)
.btnSelector(R.drawable.custom_btn_selector_primary, DialogAction.POSITIVE)
.btnSelectorStacked(R.drawable.custom_btn_selector_stacked)
.listSelector(R.drawable.custom_list_and_stackedbtn_selector)
.show();
```
The first `btnSelector` line sets a selector drawable used for all action buttons. The second `btnSelector`
line overwrites the drawable used only for the positive button. This results in the positive button having
a different selector than the neutral and negative buttons. `btnSelectorStacked` sets a selector drawable
used when the buttons become stacked, either because there's not enough room to fit them all on one line,
or because you used `forceStacked(true)` on the `Builder`. `listSelector` is used for list items, when
you are NOT using a custom adapter.
***Note***:
***An important note related to using custom action button selectors***: make sure your selector drawable references
inset drawables like the default ones do - this is important for correct action button padding.
## Gravity
It's probably unlikely you'd want to change gravity of elements in a dialog, but it's possible.
```java
new MaterialDialog.Builder(this)
.titleGravity(GravityEnum.CENTER)
.contentGravity(GravityEnum.CENTER)
.btnStackedGravity(GravityEnum.START)
.itemsGravity(GravityEnum.END)
.buttonsGravity(GravityEnum.END)
.show();
```
These are pretty self explanatory. `titleGravity` sets the gravity for the dialog title, `contentGravity`
sets the gravity for the dialog content, `btnStackedGravity` sets the gravity for stacked action buttons,
`itemsGravity` sets the gravity for list items (when you're NOT using a custom adapter).
For, `buttonsGravity` refer to this:
<table>
<tr>
<td><b>START (Default)</b></td>
<td>Neutral</td>
<td>Negative</td>
<td>Positive</td>
</tr>
<tr>
<td><b>CENTER</b></td>
<td>Negative</td>
<td>Neutral</td>
<td>Positive</td>
</tr>
<tr>
<td><b>END</b></td>
<td>Positive</td>
<td>Negative</td>
<td>Neutral</td>
</tr>
</table>
With no positive button, the negative button takes it's place except for with CENTER.
## Material Palette
To see colors that fit the Material design palette, see this page: http://www.google.com/design/spec/style/color.html#color-color-palette
---
# Global Theming
Most of the theming aspects discussed in the above section can be automatically applied to all dialogs
you show from an Activity which has a theme containing any of these attributes:
```xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!--
All dialogs will default to Theme.DARK with this set to true.
-->
<item name="md_dark_theme">true</item>
<!--
This overrides the default dark or light dialog background color.
Note that if you use a dark color here, you should set md_dark_theme to
true so text and selectors look visible
-->
<item name="md_background_color">#37474F</item>
<!--
Applies an icon next to the title in all dialogs.
-->
<item name="md_icon">@drawable/ic_launcher</item>
<!--
Limit icon to a max size.
-->
<attr name="md_icon_max_size" format="dimension" />
<!--
Limit the icon to a default max size (48dp).
-->
<attr name="md_icon_limit_icon_to_default_size" format="boolean" />
<!--
By default, the title text color is derived from the
?android:textColorPrimary system attribute.
-->
<item name="md_title_color">#E91E63</item>
<!--
By default, the content text color is derived from the
?android:textColorSecondary system attribute.
-->
<item name="md_content_color">#9C27B0</item>
<!--
By default, the link color is derived from the colorAccent attribute
of AppCompat or android:colorAccent attribute of the Material theme.
-->
<item name="md_link_color">#673AB7</item>
<!--
By default, the positive action text color is derived
from the colorAccent attribute of AppCompat or android:colorAccent
attribute of the Material theme.
-->
<item name="md_positive_color">#673AB7</item>
<!--
By default, the neutral action text color is derived
from the colorAccent attribute of AppCompat or android:colorAccent
attribute of the Material theme.
-->
<item name="md_neutral_color">#673AB7</item>
<!--
By default, the negative action text color is derived
from the colorAccent attribute of AppCompat or android:colorAccent
attribute of the Material theme.
-->
<item name="md_negative_color">#673AB7</item>
<!--
By default, a progress dialog's progress bar, check boxes, and radio buttons
have a color that is derived from the colorAccent attribute of AppCompat or
android:colorAccent attribute of the Material theme.
-->
<item name="md_widget_color">#673AB7</item>
<!--
By default, the list item text color is black for the light
theme and white for the dark theme.
-->
<item name="md_item_color">#9C27B0</item>
<!--
This overrides the color used for the top and bottom dividers used when
content is scrollable
-->
<item name="md_divider_color">#E91E63</item>
<!--
This overrides the color used for the ripple displayed on action buttons (Lollipop and above).
Defaults to the colorControlHighlight attribute from AppCompat OR the Material theme.
-->
<item name="md_btn_ripple_color">#E91E63</item>
<!--
This overrides the selector used on list items.
-->
<item name="md_list_selector">@drawable/selector</item>
<!--
This overrides the selector used on stacked action buttons.
-->
<item name="md_btn_stacked_selector">@drawable/selector</item>
<!--
This overrides the background selector used on the positive action button.
-->
<item name="md_btn_positive_selector">@drawable/selector</item>
<!--
This overrides the background selector used on the neutral action button.
-->
<item name="md_btn_neutral_selector">@drawable/selector</item>
<!--
This overrides the background selector used on the negative action button.
-->
<item name="md_btn_negative_selector">@drawable/selector</item>
<!--
This sets the gravity used while displaying the dialog title, defaults to start.
Can be start, center, or end.
-->
<item name="md_title_gravity">start</item>
<!--
This sets the gravity used while displaying the dialog content, defaults to start.
Can be start, center, or end.
-->
<item name="md_content_gravity">start</item>
<!--
This sets the gravity used while displaying the list items (not including custom adapters), defaults to start.
Can be start, center, or end.
-->
<item name="md_items_gravity">start</item>
<!--
This sets the gravity used while displaying the dialog action buttons, defaults to start.
START (Default) Neutral Negative Positive
CENTER: Negative Neutral Positive
END: Positive Negative Neutral
-->
<item name="md_buttons_gravity">start</item>
<!--
This sets the gravity used while displaying the stacked action buttons, defaults to end.
Can be start, center, or end.
-->
<item name="md_btnstacked_gravity">end</item>
<!--
The name of font in assets/fonts used on titles and action buttons
(null uses device default). E.g. [your-project]/app/main/assets/fonts/[medium]
-->
<item name="md_medium_font">Roboto-Medium.ttf</item>
<!--
The name of font in assets/fonts used everywhere else, like content and list items
(null uses device default). E.g. [your-project]/app/main/assets/fonts/[regular]
-->
<item name="md_regular_font">Roboto-Regular.ttf</item>
</style>
```
The action button color is also derived from the `android:colorAccent` attribute of the Material theme,
or `colorAccent` attribute of the AppCompat Material theme as seen in the sample project. Manually setting
the color will override that behavior.
---
# Show, Cancel, and Dismiss Callbacks
You can directly setup show/cancel/dismiss listeners from the `Builder` rather than on the resulting
`MaterialDialog` instance.
Also note that the `Builder` has a `cancelable()` method that lets you disable dismissing the dialog
when you tap outside the dialog window.
```java
new MaterialDialog.Builder(this)
.title("Use Google's Location Services?")
.content("Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.")
.positiveText("Agree")
.showListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
}
})
.cancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
}
})
.dismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
})
.show();
```
---
# Input Dialogs
An input dialog is pretty self explanatory, it retrieves input from the user of your application with
an input field (EditText). You can also display content above the EditText if you desire.
```java
new MaterialDialog.Builder(this)
.title(R.string.input)
.content(R.string.input_content)
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)
.input(R.string.input_hint, R.string.input_prefill, new MaterialDialog.InputCallback() {
@Override
public void onInput(MaterialDialog dialog, CharSequence input) {
// Do something
}
}).show();
```
The input dialog will automatically handle focusing the EditText and displaying the keyboard to allow
the user to immediately enter input. When the dialog is closed, the keyboard will be automatically dismissed.
**Note that the dialog will force the positive action button to be visible, when it's pressed the input
is submitted to the callback.**
**Also Note that the call to `inputType()` is optional.**
## Coloring the EditText
Like action buttons and many other elements of the Material dialog, you can customize the color of a
input dialog's `EditText`. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
Note that by default, EditTexts will be colored with the color held in `colorAccent` (for AppCompat)
or `android:colorAccent` (for the Material theme) in your Activity's theme.
There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
## Limiting Input Length
The code below will show a little indicator in the input dialog that tells the user how many characters they've
typed. If they type less than 2 characters, or more than 20, the dialog won't allow the input to be submitted.
It will also color the input field and character counter in error color passed for the third parameter.
If you pass 0 for the min length, there will be no min length. If you pass -1 for the max length, there will
be no max length. If you don't pass a third parameter at all, it will default to Material red.
```java
new MaterialDialog.Builder(this)
.title(R.string.input)
.inputRangeRes(2, 20, R.color.material_red_500)
.input(null, null, new MaterialDialog.InputCallback() {
@Override
public void onInput(MaterialDialog dialog, CharSequence input) {
// Do something
}
}).show();
```
*Note that `inputRangeRes(int, int, int)` takes a color resource ID for the third parameter, while
`inputRange(int, int, int)` takes a literal color integer for the second parameter. You can use either one, or use
the variation that doesn't take a third parameter at all.
## Custom Invalidation
The easiest way to invalidate (enable or disable the EditText based on whether you think the input is acceptable)
input dialogs is to call `alwaysCallInputCallback()` from the `Builder` so that the callback is invoked
every time the user changes their input. From there, you can constantly check what they've typed. If you
decide they shouldn't be able to submit that, you can disable the submit button using this from within the callback:
```java
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
```
---
# Progress Dialogs
This library allows you to display progress dialogs with Material design that even use your app's
accent color to color the progress bars (if you use AppCompat to theme your app, or the Material theme on Lollipop).
## Proguard
Normally, `ObjectAnimator` in the context it's used in this library (for custom progress drawables) would
need special proguard rules so that certain elements aren't removed when your app is built in release mode.
Luckily, AAR packages are allowed to specify proguard rules that get included in apps that depend on them.
So you do not need to worry about including any Proguard rules in order to ensure progress bars behave well.
## Indeterminate Progress Dialogs
This will display the classic progress dialog with a spinning circle, see the sample project to see it in action:
```java
new MaterialDialog.Builder(this)
.title(R.string.progress_dialog)
.content(R.string.please_wait)
.progress(true, 0)
.show();
```
## Determinate (Seek Bar) Progress Dialogs
If a dialog is not indeterminate, it displays a horizontal progress bar that increases up until a max value.
The comments in the code explain what this does.
```java
// Create and show a non-indeterminate dialog with a max value of 150
// If the showMinMax parameter is true, a min/max ratio will be shown to the left of the seek bar.
boolean showMinMax = true;
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.progress_dialog)
.content(R.string.please_wait)
.progress(false, 150, showMinMax)
.show();
// Loop until the dialog's progress value reaches the max (150)
while (dialog.getCurrentProgress() != dialog.getMaxProgress()) {
// If the progress dialog is cancelled (the user closes it before it's done), break the loop
if (dialog.isCancelled()) break;
// Wait 50 milliseconds to simulate doing work that requires progress
try {
Thread.sleep(50);
} catch (InterruptedException e) {
break;
}
// Increment the dialog's progress by 1 after sleeping for 50ms
dialog.incrementProgress(1);
}
// When the loop exits, set the dialog content to a string that equals "Done"
dialog.setContent(getString(R.string.done));
```
See the sample project for this dialog in action, with the addition of threading.
## Make an Indeterminate Dialog Horizontal
By default, indeterminate progress dialogs use a circular progress indicator. From the `Builder`,
you can tell the dialog that it needs to use a horizontal indicator when displaying an indeterminate progress
dialog:
```java
new MaterialDialog.Builder(this)
.title(R.string.progress_dialog)
.content(R.string.please_wait)
.progress(true, 0)
.progressIndeterminateStyle(true)
.show();
```
## Coloring the Progress Bar
Like action buttons and many other elements of the Material dialog, you can customize the color of a
progress dialog's progress bar. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
Note that by default, progress bars will be colored with the color held in `colorAccent` (for AppCompat)
or `android:colorAccent` (for the Material theme) in your Activity's theme.
There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
## Custom Number and Progress Formats
Like the stock `ProgressDialog`, you can format the progress min/max numbers and the percentage indicator
of determinate dialogs.
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
.progress(false, 150, true)
...
.progressNumberFormat("%1d/%2d")
.progressPercentFormat(NumberFormat.getPercentageInstance())
...
.show();
```
The values passed above are the default.
---
# Tint Helper
You can use the `MDTintHelper` class to dynamically color check boxes, radio buttons, edit texts, and progress bars
(to get around not being able to change `styles.xml` at runtime). It is used in the library to dynamically color
UI elements to match your set `widgetColor`.
---
# Misc
If you don't want the dialog to automatically be dismissed when an action button is pressed or when
the user selects a list item:
```java
MaterialDialog dialog = new MaterialDialog.Builder(this)
// ... other initialization
.autoDismiss(false)
.show();
```
---
# Color Chooser Dialogs
The Builder is used like this:
```java
// Pass a context, along with the title of the dialog
new ColorChooserDialog.Builder(this, R.string.color_palette)
.titleSub(R.string.colors) // title of dialog when viewing shades of a color
.accentMode(accent) // when true, will display accent palette instead of primary palette
.doneButton(R.string.md_done_label) // changes label of the done button
.cancelButton(R.string.md_cancel_label) // changes label of the cancel button
.backButton(R.string.md_back_label) // changes label of the back button
.preselect(accent ? accentPreselect : primaryPreselect) // optionally preselects a color
.dynamicButtonColor(true) // defaults to true, false will disable changing action buttons' color to currently selected color
.show(this); // an AppCompatActivity which implements ColorCallback
```
The Activity/Fragment you show the dialog in must implement `ColorCallback`:
```java
public class MyActivity implements ColorChooserDialog.ColorCallback {
// ...
@Override
public void onColorSelection(ColorChooserDialog dialog, @ColorInt int color) {
// TODO
}
}
```
---
You can also specify custom colors to be displayed if you don't want to use the built-in primary or accent
color palettes (which consist of the entire Material Design Color Palette):
```java
int[] primary = new int[] {
Color.parseColor("#F44336")
};
int[][] secondary = new int[][] {
new int[] { Color.parseColor("#EF5350"), Color.parseColor("#F44336"), Color.parseColor("#E53935") }
};
new ColorChooserDialog.Builder(this, R.string.color_palette)
.titleSub(R.string.colors)
.customColors(primary, secondary)
.show(this);
```
The first parameter for primary colors can also take an array resource (`R.array.colors`), which can be
seen in the sample project. If you pass `null` for the second parameter, there will be no sub levels displayed
for top level colors.
## Finding Visible Dialogs
Since the `ColorChooserDialog` is a `DialogFragment`, it attaches to your Activity/Fragment through its `FragmentManager`.
`ColorChooserDialog` has a utility method called `findVisible(AppCompatActivity, String)` that will
find a visible color chooser if any is visible:
```java
ColorChooserDialog primary = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_PRIMARY);
ColorChooserDialog accent = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_ACCENT);
ColorChooserDialog custom = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_CUSTOM);
```
## User Color Input
By default, color chooser dialogs allow the user to input a custom color using RGB sliders or a Hexadecimal input field.
This can be disabled if you don't want users to be able to use it:
```java
new ColorChooserDialog.Builder(this, R.string.color_palette)
.allowUserColorInput(false)
.customButton(R.string.md_custom_label)
.presetsButton(R.string.md_presets_label)
.show(this);
```
If you want the user to be able to input a custom color, but don't want them to be able to change transparency (alpha):
```java
new ColorChooserDialog.Builder(this, R.string.color_palette)
.allowUserColorInputAlpha(false)
.customButton(R.string.md_custom_label)
.presetsButton(R.string.md_presets_label)
.show(this);
```
---
# Preference Dialogs
Android's `EditTextPreference`, `ListPreference`, and `MultiSelectListPreference` allow you to associate a preference activity's settings
with user input that's received through typing or selection. Material Dialogs includes `MaterialEditTextPreference`,
`MaterialListPreference`, and `MaterialMultiSelectListPreference` classes that can be used in your preferences XML to automatically use Material-themed
dialogs. See the sample project for details.
By default, all of these preference classes will set their layout to `R.layout.md_preference_custom`. If you
don't want a default layout to be set, you can provide an attribute on the preferences in your XML:
```
app:useStockLayout="true"
```
---
# File Selector Dialogs
The Builder is used like this:
```java
new FileChooserDialog.Builder(this)
.initialPath("/sdcard/Download") // changes initial path, defaults to external storage directory
.mimeType("image/*") // Optional MIME type filter
.extensionsFilter(".png", ".jpg") // Optional extension filter, will override mimeType()
.tag("optional-identifier")
.goUpLabel("Up") // custom go up label, default label is "..."
.show(this); // an AppCompatActivity which implements FileCallback
```
The Activity/Fragment you show the dialog in must implement `FileCallback`:
```java
public class MyActivity implements FileChooserDialog.FileCallback {
// ...
@Override
public void onFileSelection(FileChooserDialog dialog, File file) {
// TODO
final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
}
}
```
---
# Folder Selector Dialogs
The Builder is used like this:
```java
// Pass AppCompatActivity which implements FolderCallback
new FolderChooserDialog.Builder(this)
.chooseButton(R.string.md_choose_label) // changes label of the choose button
.initialPath("/sdcard/Download") // changes initial path, defaults to external storage directory
.tag("optional-identifier")
.goUpLabel("Up") // custom go up label, default label is "..."
.show(this);
```
The Activity/Fragment you show the dialog in must implement `FolderCallback`:
```java
public class MyActivity implements FolderChooserDialog.FolderCallback {
// ...
@Override
public void onFolderSelection(FolderChooserDialog dialog, File folder) {
// TODO
final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
}
}
```
---
Optionally, you can allow users to have the ability to create new folders from this dialog:
```java
new FolderChooserDialog.Builder(this)
.chooseButton(R.string.md_choose_label) // changes label of the choose button
.initialPath("/sdcard/Download") // changes initial path, defaults to external storage directory
.tag("optional-identifier")
.allowNewFolder(true, R.string.new_folder) // pass 0 in the second parameter to use default button label
.show(this);
```
---
# Simple List Dialogs
Simple List Dialogs are a specific style of list dialogs taken from the Material Design Guidelines: https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
This library's implementation is just a pre-made adapter that you can pass to the `MaterialDialog.Builder`.
```java
final MaterialSimpleListAdapter adapter = new MaterialSimpleListAdapter(new MaterialSimpleListAdapter.Callback() {
@Override
public void onMaterialListItemSelected(MaterialDialog dialog, int index, MaterialSimpleListItem item) {
// TODO
}
});
adapter.add(new MaterialSimpleListItem.Builder(this)
.content("username@gmail.com")
.icon(R.drawable.ic_account_circle)
.backgroundColor(Color.WHITE)
.build());
adapter.add(new MaterialSimpleListItem.Builder(this)
.content("user02@gmail.com")
.icon(R.drawable.ic_account_circle)
.backgroundColor(Color.WHITE)
.build());
adapter.add(new MaterialSimpleListItem.Builder(this)
.content(R.string.add_account)
.icon(R.drawable.ic_content_add)
.iconPaddingDp(8)
.build());
new MaterialDialog.Builder(this)
.title(R.string.set_backup)
.adapter(adapter, null)
.show();
```
---
\ No newline at end of file
3.3.0
* Added `md_line_spacing_body` global theme attribute, which sets a global default for message line
spacing. See #1903.
* Added some assertions and sanity checks to avoid choice list adapter out of bounds crashes.
See #1906.
* Corner radius should not apply to the bottom of bottom sheet dialogs. See #1941.
* Fix dialog titles being cut off with custom fonts. See #1936.
* If `noVerticalPadding` is set with `customView(...)``, padding is not applied to the bottom of
the content `ScrollView` if `scrollable` is enabled. Resolves #1834.
* Input dialog styling is not enforced by the dialog. The global default for `TextInputLayout`
(`textInputStyle`) is used instead. See #1857.
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册