1
0
Форкнуть 0
This commit is contained in:
Diego Ezequiel Guillén 2022-04-19 19:31:50 -03:00
Коммит bc33bbce65
132 изменённых файлов: 2336 добавлений и 0 удалений

Двоичные данные
.DS_Store поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
._.DS_Store Normal file

Двоичный файл не отображается.

Двоичные данные
._.github Normal file

Двоичный файл не отображается.

Двоичные данные
._CONTRIBUTING.md Normal file

Двоичный файл не отображается.

Двоичные данные
._LICENSE Normal file

Двоичный файл не отображается.

Двоичные данные
._README.md Normal file

Двоичный файл не отображается.

Двоичные данные
._app Normal file

Двоичный файл не отображается.

Двоичные данные
._build.gradle Normal file

Двоичный файл не отображается.

Двоичные данные
._code-of-conduct.md Normal file

Двоичный файл не отображается.

Двоичные данные
._gradle Normal file

Двоичный файл не отображается.

Двоичные данные
._gradle.properties Normal file

Двоичный файл не отображается.

Двоичные данные
._gradlew Normal file

Двоичный файл не отображается.

Двоичные данные
._gradlew.bat Normal file

Двоичный файл не отображается.

Двоичные данные
._settings.gradle Normal file

Двоичный файл не отображается.

2
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

Двоичные данные
.github/._ISSUE_TEMPLATE поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
.github/ISSUE_TEMPLATE/._android-basics-dogglers-app.md поставляемый Normal file

Двоичный файл не отображается.

32
.github/ISSUE_TEMPLATE/android-basics-dogglers-app.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
---
name: 'Android Basics: Dogglers app'
about: Describe this issue template's purpose here.
title: 'Android Basics: Dogglers app'
labels: ''
assignees: ''
---
**URL of codelab**
**In which task and step of the codelab can this issue be found?**
**Describe the problem**
**Steps to reproduce?**
1. Go to...
2. Click on...
3. See error...
**Versions**
_Android Studio version:_
_API version of the emulator:_
**Additional information**
_Include screenshots if they would be useful in clarifying the problem._

30
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,30 @@
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Log/OS Files
*.log
# Android Studio generated files and folders
captures/
.externalNativeBuild/
.cxx/
*.apk
output.json
# IntelliJ
*.iml
.idea/
# Keystore files
*.jks
*.keystore
# Google Services (e.g. APIs or Firebase)
google-services.json
# Android Profiling
*.hprof

29
CONTRIBUTING.md Normal file
Просмотреть файл

@ -0,0 +1,29 @@
# How to Contribute
We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement (CLA). You (or your employer) retain the copyright to your
contribution; this simply gives us permission to use and redistribute your
contributions as part of the project. Head over to
<https://cla.developers.google.com/> to see your current agreements on file or
to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
## Community Guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).

201
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

27
README.md Normal file
Просмотреть файл

@ -0,0 +1,27 @@
Dogglers - Starter Code
==================================
Starter code for the second independent project for [Android Basics in Kotlin](https://developer.android.com/courses/android-basics-kotlin/course).
Introduction
------------
This is the starter code for the Dogglers app project in the [final pathway](https://developer.android.com/courses/pathways/android-basics-kotlin-unit-2-pathway-3) of Android Basics [Unit 2](https://developer.android.com/courses/android-basics-kotlin/unit-2). This project is an opportunity for you to demonstrate the concepts you learned in the unit.
Pre-requisites
--------------
- Complete [Unit 2](https://developer.android.com/courses/android-basics-kotlin/unit-2) of Android Basics in Kotlin
Getting Started
---------------
1. Download the starter code
2. Open the project in Android Studio
3. Complete the project in accordance with the [project instructions](https://developer.android.com/codelabs/basic-android-kotlin-training-project-dogglers-app?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-kotlin-unit-2-pathway-3%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-training-project-dogglers-app#0)
Tips
----
- Use the provided tests to ensure your app is running as expected
- DO NOT ALTER THE PROVIDED TESTS

Двоичные данные
app/.DS_Store поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
app/._.DS_Store Normal file

Двоичный файл не отображается.

Двоичные данные
app/._build.gradle Normal file

Двоичный файл не отображается.

Двоичные данные
app/._proguard-rules.pro Normal file

Двоичный файл не отображается.

Двоичные данные
app/._src Normal file

Двоичный файл не отображается.

67
app/build.gradle Normal file
Просмотреть файл

@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example.dogglers"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures{
viewBinding = true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'
debugImplementation "androidx.fragment:fragment-testing:1.3.3"
}

21
app/proguard-rules.pro поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

Двоичные данные
app/src/._androidTest Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/._main Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/._java Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/java/._com Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/java/com/._example Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/java/com/example/._dogglers Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/java/com/example/dogglers/._BaseTest.kt Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/java/com/example/dogglers/._ButtonTests.kt Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/androidTest/java/com/example/dogglers/._GridListTests.kt Normal file

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,171 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewAssertion
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.BoundedMatcher
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.example.dogglers.BaseTest.DrawableMatcher.withDrawable
import com.example.dogglers.data.DataSource
import org.hamcrest.CoreMatchers
import org.hamcrest.Description
import org.hamcrest.Matcher
import java.lang.IllegalStateException
open class BaseTest {
val lastPosition = DataSource.dogs.size - 1
/**
* Check the content of a card
*
* @param name
* @param age The full age string as it appears on the screen
* @param hobbies The full hobbies string as it appears on the screen
* @param imageResource The image resource Id
*/
private fun hasListItemContent(name: String, age: String, hobbies: String, imageResource: Int) {
onView(withText(name))
.check(matches(isDisplayed()))
onView(withText(age))
.check(matches(isDisplayed()))
onView(withText(hobbies))
.check(matches(isDisplayed()))
onView(withDrawable(imageResource))
.check(matches(isDisplayed()))
}
/**
* Check the content of the first card
*/
fun checkFirstPosition() {
hasListItemContent("Tzeitel", "Age: 7", "Hobbies: sunbathing",
R.drawable.tzeitel)
}
/**
* Custom matcher to find drawable.
*/
object DrawableMatcher {
/**
* Invokes the [RecyclerViewAssertion] to check the RecyclerView has the correct count
*
* @param count The expected number of items in the RecyclerView adapter
*/
fun hasItemCount(count: Int): ViewAssertion {
return RecyclerViewAssertion(count)
}
fun withDrawable(@DrawableRes resourceId: Int): Matcher<View> {
return object : BoundedMatcher<View, ImageView>(ImageView::class.java) {
override fun describeTo(description: Description?) {
description!!.appendText("has drawable resource $resourceId")
}
override fun matchesSafely(imageView: ImageView): Boolean {
return isSameBitmap(imageView, imageView.drawable, resourceId)
}
}
}
private fun isSameBitmap(item: View, drawable: Drawable?, expectedResId: Int): Boolean {
val image = item as ImageView
if (expectedResId < 0) {
return image.drawable == null
}
val expectedDrawable: Drawable? = ContextCompat.getDrawable(item.context, expectedResId)
if (drawable == null || expectedDrawable == null) {
return false
}
// In the case we are not checking a vector drawable, we can get the bitmap directly
if (drawable is BitmapDrawable && expectedDrawable is BitmapDrawable) {
val found = drawable.bitmap
val expected = expectedDrawable.bitmap
return found.sameAs(expected)
}
// Make tint consistent just in case they differ
drawable.setTint(android.R.color.black)
expectedDrawable.setTint(android.R.color.black)
val bitmap = getBitmap(drawable)
val expectedBitmap = getBitmap(expectedDrawable)
return bitmap.sameAs(expectedBitmap)
}
/**
* Convert vector drawable to bitmap
* @param drawable vector drawable
*/
private fun getBitmap(drawable: Drawable): Bitmap {
val bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
/**
* Custom view assertion to check:
* The RecyclerView exists
* The RecyclerView has an adapter
* The adapter contains the expected number of items
*
* @param count The expected number of adapter items
*/
private class RecyclerViewAssertion(private val count: Int) : ViewAssertion {
override fun check(view: View?, noViewFoundException: NoMatchingViewException?) {
if (noViewFoundException != null) {
throw noViewFoundException
}
if (view !is RecyclerView) {
throw IllegalStateException("The view is not a RecyclerView")
}
if (view.adapter == null) {
throw IllegalStateException("No adapter assigned to RecyclerView")
}
// Check item count
ViewMatchers.assertThat(
"RecyclerView item count",
view.adapter?.itemCount,
CoreMatchers.equalTo(count)
)
}
}
}
}

Просмотреть файл

@ -0,0 +1,69 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@MediumTest
class ButtonTests {
@get:Rule
var activityRule: ActivityScenarioRule<MainActivity>
= ActivityScenarioRule(MainActivity::class.java)
@Test
fun `vertical_list_button_is_displayed`() {
onView(withId(R.id.vertical_btn)).check(matches(isDisplayed()))
}
@Test
fun `horizontal_list_button_is_displayed`() {
onView(withId(R.id.horizontal_btn)).check(matches(isDisplayed()))
}
@Test
fun `grid_list_button_is_displayed`() {
onView(withId(R.id.grid_btn)).check(matches(isDisplayed()))
}
@Test
fun `clicking_vertical_list_button_displays_vertical_list`() {
onView(withId(R.id.vertical_btn)).perform(click())
onView(withId(R.id.vertical_recycler_view)).check(matches(isDisplayed()))
}
@Test
fun `clicking_horizontal_list_button_displays_horizontal_list`() {
onView(withId(R.id.horizontal_btn)).perform(click())
onView(withId(R.id.horizontal_recycler_view)).check(matches(isDisplayed()))
}
@Test
fun `clicking_grid_list_button_displays_grid_list`() {
onView(withId(R.id.grid_btn)).perform(click())
onView(withId(R.id.grid_recycler_view)).check(matches(isDisplayed()))
}
}

Просмотреть файл

@ -0,0 +1,68 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.swipeUp
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.example.dogglers.BaseTest.DrawableMatcher.hasItemCount
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
class GridListTests : BaseTest() {
@get:Rule
var activityRule: ActivityScenarioRule<GridListActivity>
= ActivityScenarioRule(GridListActivity::class.java)
@Test
fun `grid_list_content_at_first_position`() {
checkFirstPosition()
}
@Test
fun `grid_list_content_on_first_page`() {
onView(withText("Nox")).check(matches(isDisplayed()))
}
@Test
fun `grid_list_content_at_last_position`() {
onView(withId(R.id.grid_recycler_view))
.perform(scrollToPosition<RecyclerView.ViewHolder>(lastPosition))
onView(withText("Bella")).check(matches(isDisplayed()))
}
@Test
fun `vertical_scrolling`() {
onView(withId(R.id.grid_recycler_view))
.perform(swipeUp())
onView(withText("Bella")).check(matches(isDisplayed()))
}
@Test
fun `recycler_view_item_count`() {
onView(withId(R.id.grid_recycler_view)).check(hasItemCount(6))
}
}

Просмотреть файл

@ -0,0 +1,63 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.swipeLeft
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.example.dogglers.BaseTest.DrawableMatcher.hasItemCount
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
class HorizontalListTests : BaseTest() {
@get:Rule
var activityRule: ActivityScenarioRule<HorizontalListActivity>
= ActivityScenarioRule(HorizontalListActivity::class.java)
@Test
fun `horizontal_scroll_content_at_first_position`() {
checkFirstPosition()
}
@Test
fun `horizontal_scroll_content_at_last_position`() {
onView(withId(R.id.horizontal_recycler_view))
.perform(scrollToPosition<RecyclerView.ViewHolder>(lastPosition))
onView(withText("Bella")).check(matches(isDisplayed()))
}
@Test
fun `horizontal_scrolling`() {
onView(withId(R.id.horizontal_recycler_view))
.perform(swipeLeft())
onView(withText("Frankie")).check(matches(isDisplayed()))
}
@Test
fun `recycler_view_item_count`() {
onView(withId(R.id.horizontal_recycler_view)).check(hasItemCount(6))
}
}

Просмотреть файл

@ -0,0 +1,63 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.swipeUp
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.example.dogglers.BaseTest.DrawableMatcher.hasItemCount
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
class VerticalListTests : BaseTest() {
@get:Rule
var activityRule: ActivityScenarioRule<VerticalListActivity>
= ActivityScenarioRule(VerticalListActivity::class.java)
@Test
fun `vertical_scroll_content_at_first_position`() {
checkFirstPosition()
}
@Test
fun `vertical_scroll_content_at_last_position`() {
onView(withId(R.id.vertical_recycler_view))
.perform(scrollToPosition<RecyclerView.ViewHolder>(lastPosition))
onView(withText("Bella")).check(matches(isDisplayed()))
}
@Test
fun `vertical_scrolling`() {
onView(withId(R.id.vertical_recycler_view))
.perform(swipeUp())
onView(withText("Faye")).check(matches(isDisplayed()))
}
@Test
fun `recycler_view_item_count`() {
onView(withId(R.id.vertical_recycler_view)).check(hasItemCount(6))
}
}

Двоичные данные
app/src/main/._AndroidManifest.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/._ic_launcher-playstore.png Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/._java Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/._res Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 The Android Open Source Project.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dogglers">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Dogglers">
<activity android:name=".VerticalListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".HorizontalListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".GridListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Двоичные данные
app/src/main/ic_launcher-playstore.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 22 KiB

Двоичные данные
app/src/main/java/._com Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/._example Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/._dogglers Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._GridListActivity.kt Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._HorizontalListActivity.kt Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._MainActivity.kt Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._VerticalListActivity.kt Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._adapter Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._const Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._data Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/java/com/example/dogglers/._model Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.dogglers.adapter.DogCardAdapter
import com.example.dogglers.const.Layout
import com.example.dogglers.databinding.ActivityGridListBinding
class GridListActivity : AppCompatActivity() {
private lateinit var binding: ActivityGridListBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityGridListBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.gridRecyclerView.adapter = DogCardAdapter(
applicationContext,
Layout.GRID
)
// Specify fixed size to improve performance
binding.gridRecyclerView.setHasFixedSize(true)
// Enable up button for backward navigation
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}

Просмотреть файл

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.dogglers.adapter.DogCardAdapter
import com.example.dogglers.const.Layout
import com.example.dogglers.databinding.ActivityHorizontalListBinding
class HorizontalListActivity : AppCompatActivity() {
private lateinit var binding: ActivityHorizontalListBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHorizontalListBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.horizontalRecyclerView.adapter = DogCardAdapter(
applicationContext,
Layout.HORIZONTAL
)
// Specify fixed size to improve performance
binding.horizontalRecyclerView.setHasFixedSize(true)
// Enable up button for backward navigation
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}

Просмотреть файл

@ -0,0 +1,62 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.example.dogglers.databinding.ActivityMainBinding
import com.google.android.material.tabs.TabLayoutMediator
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var listIntent: Intent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Setup view binding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Launch the VerticalListActivity on verticalBtn click
binding.verticalBtn.setOnClickListener { launchVertical() }
// Launch the HorizontalListActivity on horizontalBtn click
binding.horizontalBtn.setOnClickListener { launchHorizontal() }
// Launch the GridListActivity on gridBtn click
binding.gridBtn.setOnClickListener { launchGrid() }
}
private fun launchVertical() {
listIntent = Intent(this, VerticalListActivity::class.java)
startActivity(listIntent)
}
private fun launchHorizontal() {
listIntent = Intent(this, HorizontalListActivity::class.java)
startActivity(listIntent)
}
private fun launchGrid() {
listIntent = Intent(this, GridListActivity::class.java)
startActivity(listIntent)
}
}

Просмотреть файл

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.dogglers.adapter.DogCardAdapter
import com.example.dogglers.const.Layout
import com.example.dogglers.databinding.ActivityVerticalListBinding
class VerticalListActivity : AppCompatActivity() {
private lateinit var binding: ActivityVerticalListBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityVerticalListBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.verticalRecyclerView.adapter = DogCardAdapter(
applicationContext,
Layout.VERTICAL
)
// Specify fixed size to improve performance
binding.verticalRecyclerView.setHasFixedSize(true)
// Enable up button for backward navigation
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}

Двоичные данные
app/src/main/java/com/example/dogglers/adapter/._DogCardAdapter.kt Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,90 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.dogglers.R
import com.example.dogglers.const.Layout.GRID
import com.example.dogglers.data.DataSource
/**
* Adapter to inflate the appropriate list item layout and populate the view with information
* from the appropriate data source
*/
class DogCardAdapter(
private val context: Context?,
private val layout: Int
): RecyclerView.Adapter<DogCardAdapter.DogCardViewHolder>() {
// TODO: Initialize the data using the List found in data/DataSource
val data = DataSource.dogs
/**
* Initialize view elements
*/
class DogCardViewHolder(view: View?): RecyclerView.ViewHolder(view!!) {
// TODO: Declare and initialize all of the list item UI components
val dogImageView: ImageView = view!!.findViewById(R.id.dog_image)
val dogNameTextView: TextView = view!!.findViewById(R.id.dog_name)
val dogAgeTextView: TextView = view!!.findViewById(R.id.dog_age)
val dogHobbiesTextView: TextView = view!!.findViewById(R.id.dog_hobbies)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DogCardViewHolder {
// TODO: Use a conditional to determine the layout type and set it accordingly.
// if the layout variable is Layout.GRID the grid list item should be used. Otherwise the
// the vertical/horizontal list item should be used.
val activityLayout =
if (layout == GRID) R.layout.grid_list_item
else R.layout.vertical_horizontal_list_item
// TODO Inflate the layout
val adapterLayout = LayoutInflater.from(parent.context).inflate(activityLayout, parent, false)
// TODO: Null should not be passed into the view holder. This should be updated to reflect
// the inflated layout.
return DogCardViewHolder(adapterLayout)
}
override fun getItemCount(): Int = data.size // TODO: return the size of the data set instead of 0
override fun onBindViewHolder(holder: DogCardAdapter.DogCardViewHolder, position: Int) {
// TODO: Get the data at the current position
val dog = data[position]
// TODO: Set the image resource for the current dog
holder.dogImageView.setImageResource(dog.imageResourceId)
// TODO: Set the text for the current dog's name
holder.dogNameTextView.text = dog.name
// TODO: Set the text for the current dog's age
val resources = context?.resources
holder.dogAgeTextView.text = resources?.getString(R.string.dog_age, dog.age)
// TODO: Set the text for the current dog's hobbies by passing the hobbies to the
// R.string.dog_hobbies string constant.
// Passing an argument to the string resource looks like:
// resources?.getString(R.string.dog_hobbies, dog.hobbies)
holder.dogHobbiesTextView.text = resources?.getString(R.string.dog_hobbies, dog.hobbies)
}
}

Двоичные данные
app/src/main/java/com/example/dogglers/const/._Layout.kt Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,27 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers.const
/**
* Static object to hold constant values to be associated with a layout.
* These values are intended to be passed into the [DogCardAdapter] to determine the type of layout
* to inflate.
*/
object Layout {
val VERTICAL = 1
val HORIZONTAL = 2
val GRID = 3
}

Двоичные данные
app/src/main/java/com/example/dogglers/data/._DataSource.kt Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,64 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers.data
import com.example.dogglers.R
import com.example.dogglers.model.Dog
/**
* An object to generate a static list of dogs
*/
object DataSource {
val dogs: List<Dog> = listOf(
Dog(
R.drawable.tzeitel,
"Tzeitel",
"7",
"sunbathing"
),
Dog(
R.drawable.leroy,
"Leroy",
"4",
"sleeping in dangerous places"
),
Dog(
R.drawable.frankie,
"Frankie",
"2",
"stealing socks"
),
Dog(
R.drawable.nox,
"Nox",
"8",
"meeting new animals"
),
Dog(
R.drawable.faye,
"Faye",
"8",
"Digging in the garden"
),
Dog(
R.drawable.bella,
"Bella",
"14",
"Chasing sea foam"
)
)
}

Двоичные данные
app/src/main/java/com/example/dogglers/model/._Dog.kt Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,28 @@
/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers.model
import androidx.annotation.DrawableRes
/**
* A data class to represent the information presented in the dog card
*/
data class Dog(
@DrawableRes val imageResourceId: Int,
val name: String,
val age: String,
val hobbies: String
)

Двоичные данные
app/src/main/res/._drawable Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/._layout Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/._mipmap-anydpi-v26 Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/._values Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/._values-night Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._bella.jpg Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._faye.jpg Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._frankie.jpg Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._ic_launcher_background.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._ic_launcher_foreground.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._leroy.jpg Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._nox.jpg Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/._tzeitel.jpg Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/drawable/bella.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 116 KiB

Двоичные данные
app/src/main/res/drawable/faye.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 117 KiB

Двоичные данные
app/src/main/res/drawable/frankie.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 176 KiB

Просмотреть файл

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 The Android Open Source Project.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.6"
android:scaleY="0.6">
<path
android:pathData="M0,0h180v180h-180z"
android:fillColor="#c3e2fc"/>
<path
android:pathData="M0,48.075h180v78.283h-180z"
android:fillColor="#e7f4fd"/>
</group>
</vector>

Просмотреть файл

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 The Android Open Source Project.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.6"
android:scaleY="0.6">
<group>
<clip-path
android:pathData="M0,0h180v180h-180z"/>
<path
android:pathData="M45.851,87.198m-31.932,0a31.932,31.932 0,1 1,63.864 0a31.932,31.932 0,1 1,-63.864 0"
android:fillColor="#fff"/>
<path
android:pathData="M45.851,7.457m-31.932,0a31.932,31.932 0,1 1,63.864 0a31.932,31.932 0,1 1,-63.864 0"
android:fillColor="#fff"/>
<path
android:pathData="M90,64.876h51.476v11.801h-51.476z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,81.316h63.742v11.801h-63.742z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,97.755h63.742v11.801h-63.742z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,144.635h51.476v11.801h-51.476z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,161.074h63.742v11.801h-63.742z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,177.514h63.742v11.801h-63.742z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,-1.432h63.742v11.801h-63.742z"
android:fillColor="#9bd0fa"/>
<path
android:pathData="M90,15.007h63.742v11.801h-63.742z"
android:fillColor="#9bd0fa"/>
<group>
<clip-path
android:pathData="M45.851,87.198m-31.932,0a31.932,31.932 0,1 1,63.864 0a31.932,31.932 0,1 1,-63.864 0"/>
<path
android:pathData="M63.153,124.067H24.267c0.784,-4.631 3.03,-11.026 5.31,-17.916A26.832,26.832 0,0 0,30.934 97.6L30.87,85.1H59.643l0.84,12.483a21.131,21.131 0,0 0,1.019 5.222c3.3,9.947 6.414,14.229 6.733,21.258Z"
android:fillColor="#4caa51"/>
<path
android:pathData="M34.562,123.936a18.735,18.735 0,0 0,0.946 -5.983h0a8.719,8.719 0,0 1,8.719 -8.763h3.264a8.718,8.718 0,0 1,8.7 8.133l0.042,0.621a41.953,41.953 0,0 0,1.477 6.123"
android:fillColor="#cfe9cf"/>
<path
android:pathData="M40.735,67.825h9.891A11.527,11.527 0,0 1,62.153 79.352v9.9a16.335,16.335 0,0 1,-16.335 16.335h-0.275A16.335,16.335 0,0 1,29.208 89.254v-9.9A11.527,11.527 0,0 1,40.735 67.825Z"
android:fillColor="#cfe9cf"/>
<path
android:pathData="M39.534,67.093l-0.167,1.279a0.6,0.6 0,0 1,0.543 -0.069l0.821,0.441a1.66,1.66 0,0 1,0.736 0.79c0.969,2.2 2.274,4.421 2.274,6.787l-0.847,7.766A6.616,6.616 0,0 1,40.071 88.8,9.37 9.37,0 0,0 36,96.5v2.782a6.753,6.753 0,0 0,6.833 6.67h5.7a6.752,6.752 0,0 0,6.832 -6.67V96.5A9.371,9.371 0,0 0,51.3 88.8a6.806,6.806 0,0 1,-2.95 -4.984L47.69,76.2q0,-0.941 0.092,-1.876a8.991,8.991 0,0 1,3.07 -5.091,1 1,0 0,1 0.9,-0.192l-0.491,-1.947C48.822,67.037 41.929,67.035 39.534,67.093Z"
android:fillColor="#ebf6ec"/>
<path
android:pathData="M46.961,95.748l-2.561,-0a2.487,2.487 0,0 1,-2.487 -2.487l-0,-0.148a3.524,3.524 0,0 1,3.524 -3.524l0.486,-0a3.524,3.524 0,0 1,3.524 3.524l-0,0.148A2.487,2.487 0,0 1,46.961 95.748Z"
android:fillColor="#4caa51"/>
<path
android:pathData="M36.698,81.082a1.874,2.295 0,1 0,3.748 0a1.874,2.295 0,1 0,-3.748 0z"
android:fillColor="#71c375"/>
<path
android:pathData="M50.147,81.082a1.874,2.295 0,1 0,3.748 0a1.874,2.295 0,1 0,-3.748 0z"
android:fillColor="#71c375"/>
<path
android:pathData="M50.723,81.787a1.298,1.589 0,1 0,2.596 0a1.298,1.589 0,1 0,-2.596 0z"
android:fillColor="#4caa51"/>
<path
android:pathData="M37.331,81.857a1.241,1.519 0,1 0,2.482 0a1.241,1.519 0,1 0,-2.482 0z"
android:fillColor="#4caa51"/>
<path
android:pathData="M38.825,66.945l-8.689,2.32a3.889,3.889 0,0 0,-2 1.279c-1.765,2.132 -5.873,7.09 -5.977,7.186a0.893,0.893 0,0 0,-0.1 1.134l8.552,13.242a0.669,0.669 0,0 0,1.21 -0.219l1.83,-11.664A10.035,10.035 0,0 1,34.8 76.9l4.822,-8.66c0.006,-0.011 0.209,-0.434 0.385,-0.8a0.371,0.371 0,0 0,-0.346 -0.531C39.246,66.918 38.847,66.934 38.825,66.945Z"
android:fillColor="#4caa51"/>
<path
android:pathData="M70.093,76.1l-7.6,-5.884a5.147,5.147 0,0 0,-1.817 -0.9l-8.159,-2.179h0l-0.73,-0.2a1.08,1.08 0,0 0,-0.2 -0.021,0.507 0.507,0 0,0 -0.522,0.622 15.582,15.582 0,0 0,0.45 1.636l4.377,7.862a9.089,9.089 0,0 1,1.04 3.018l1.856,11.825a0.669,0.669 0,0 0,1.21 0.219L70.36,77.352A0.868,0.868 0,0 0,70.093 76.1Z"
android:fillColor="#4caa51"/>
<path
android:pathData="M47.456,103.033c-1.392,-0.28 -1.4,-0.919 -1.4,-0.919l-0.227,-8.805 -0.178,8.809s0,0.636 -1.384,0.934 -4.06,-1.13 -4.7,-1.821a7.56,7.56 0,0 0,4.7 2.4s0.869,0.185 1.588,-0.933c0.73,1.108 1.6,0.914 1.6,0.914a7.569,7.569 0,0 0,4.674 -2.463C51.5,101.848 48.847,103.314 47.456,103.033Z"
android:fillColor="#4caa51"/>
</group>
<group>
<clip-path
android:pathData="M45.851,166.975m-31.932,0a31.932,31.932 0,1 1,63.864 0a31.932,31.932 0,1 1,-63.864 0"/>
<path
android:pathData="M45.851,166.975m-31.932,0a31.932,31.932 0,1 1,63.864 0a31.932,31.932 0,1 1,-63.864 0"
android:fillColor="#fff"/>
<path
android:pathData="M56.192,193.7H32.4a130.717,130.717 0,0 1,3.249 -13.561,63.382 63.382,0 0,0 1.7,-10.333l2.419,-5.6H54.044l0.3,7.472c0.073,1.344 1.582,5.2 1.924,6.483 2.018,7.53 2.839,10.217 3.035,15.537Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M37.733,191.8a25.529,25.529 0,0 0,0.664 -5.9h0c-0.018,-4.769 1.271,-8.647 4.661,-8.647h5.569c3.218,0 4.061,3.508 4.277,8.026l0.029,0.613a55.755,55.755 0,0 0,1.036 6.042"
android:fillColor="#fff6a7"/>
<path
android:pathData="M31.1,150.968a21.378,21.378 0,0 0,-4.936 3.145c-1.476,1.334 -0.877,3.031 -0.539,4.728 1.05,5.258 3.614,10.772 7.89,14.2a1.054,1.054 0,0 0,0.578 0.057,1.185 1.185,0 0,0 0.76,-0.991c0.154,-1.482 0.267,-3 0.3,-4.489a75.341,75.341 0,0 1,0.673 -11.22,12.976 12.976,0 0,1 2.339,-5.381c0.552,-0.754 1.5,-1.366 2.017,-2.146A20.483,20.483 0,0 0,31.1 150.968Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M33.148,154.408c-0.575,3.107 0.7,6.427 2.086,9.406a48.663,48.663 0,0 1,0.6 -7.417,12.976 12.976,0 0,1 2.339,-5.381c0.552,-0.754 1.5,-1.366 2.017,-2.146 -0.569,0 -1.135,0.026 -1.7,0.073C36.057,150.112 33.636,151.771 33.148,154.408Z"
android:fillColor="#fbc833"/>
<path
android:pathData="M60.52,150.864a21.37,21.37 0,0 1,4.975 3.082c1.493,1.314 0.916,3.017 0.6,4.719 -0.982,5.273 -3.473,10.818 -7.7,14.3a1.062,1.062 0,0 1,-0.579 0.064,1.184 1.184,0 0,1 -0.772,-0.982c-0.174,-1.479 -0.3,-3 -0.361,-4.484a75.242,75.242 0,0 0,-0.817 -11.21A12.961,12.961 0,0 0,53.451 151c-0.56,-0.747 -1.514,-1.348 -2.043,-2.121A20.487,20.487 0,0 1,60.52 150.864Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M56.581,164.529a22.684,22.684 0,0 0,0.991 -3.08,24.164 24.164,0 0,0 0.98,-5.893c-0.034,-2.2 -1.268,-3.7 -2.8,-5.134 -0.362,-0.343 -0.862,-0.9 -1.407,-1.366a19.63,19.63 0,0 0,-2.939 -0.173c0.529,0.773 1.483,1.374 2.043,2.121a12.961,12.961 0,0 1,2.41 5.349A52.6,52.6 0,0 1,56.581 164.529Z"
android:fillColor="#fbc833"/>
<path
android:pathData="M55.863,162.749a15.615,15.615 0,0 0,0.982 -2.639c0.534,-2.3 1.105,-5.138 -0.2,-7.314a10.889,10.889 0,0 0,-5.712 -4.386,12.727 12.727,0 0,0 -9.908,-0.106c-2.531,1.058 -4.746,2.465 -6.011,4.632 -1.283,2.193 -0.676,5.023 -0.113,7.316a16,16 0,0 0,1.016 2.626c0.033,0.084 0.065,0.17 0.1,0.256 0.641,1.754 -0.13,3.279 -0.547,4.985 -0.583,2.377 1.156,4.019 3.243,5.394a12.559,12.559 0,0 0,7.263 1.7,12.545 12.545,0 0,0 7.241,-1.8c2.069,-1.4 3.785,-3.066 3.173,-5.436 -0.439,-1.7 -1.23,-3.213 -0.611,-4.976C55.8,162.921 55.833,162.835 55.863,162.749Z"
android:fillColor="#fffdea"/>
<path
android:pathData="M55.863,162.749a15.615,15.615 0,0 0,0.982 -2.639c0.534,-2.3 1.105,-5.138 -0.2,-7.314a10.889,10.889 0,0 0,-5.712 -4.386,15.912 15.912,0 0,0 -3.295,-0.9c0.022,2.729 0.065,5.458 0.276,8.179 0.24,3.083 0.651,6.226 2.522,8.951 1.365,1.991 3.505,4.38 3.164,6.824a5.109,5.109 0,0 1,-1.064 2.369c0.235,-0.128 0.462,-0.263 0.678,-0.41 2.069,-1.4 3.785,-3.066 3.173,-5.436 -0.439,-1.7 -1.23,-3.213 -0.611,-4.976C55.8,162.921 55.833,162.835 55.863,162.749Z"
android:fillColor="#fff6a7"/>
<path
android:pathData="M38.188,168.4c0.8,-1.312 2.12,-2.31 2.992,-3.578a11.879,11.879 0,0 0,1.923 -5.456,104.1 104.1,0 0,0 0.682,-11.859 12.39,12.39 0,0 0,-2.765 0.8c-2.531,1.058 -4.746,2.465 -6.011,4.632 -1.283,2.193 -0.676,5.023 -0.113,7.316a16,16 0,0 0,1.016 2.626c0.033,0.084 0.065,0.17 0.1,0.256 0.641,1.754 -0.13,3.279 -0.547,4.985 -0.583,2.377 1.156,4.019 3.243,5.394a9.807,9.807 0,0 0,2.689 1.2C38.569,173.312 36.558,171.07 38.188,168.4Z"
android:fillColor="#fff6a7"/>
<path
android:pathData="M47.126,173.69c-1.02,-0.206 -1.024,-0.674 -1.024,-0.674l-0.167,-2.969 -0.13,2.972s0,0.466 -1.015,0.684 -2.976,-0.828 -3.446,-1.335a5.543,5.543 0,0 0,3.45 1.76s0.636,0.136 1.163,-0.684c0.536,0.812 1.171,0.67 1.171,0.67a5.546,5.546 0,0 0,3.427 -1.805C50.092,172.821 48.146,173.9 47.126,173.69Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M50.333,167.556c0.009,1.243 -1.955,3.28 -4.393,3.3s-4.428,-2 -4.437,-3.24 1.963,-2.261 4.4,-2.279S50.326,166.313 50.333,167.556Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M42.48,159.523a1.368,1.368 0,1 1,-1.377 -1.357A1.37,1.37 0,0 1,42.48 159.523Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M42.072,159.788a0.949,0.949 0,1 1,-0.955 -0.942A0.951,0.951 0,0 1,42.072 159.788Z"
android:fillColor="#fbc833"/>
<path
android:pathData="M52.026,159.426a1.405,1.405 0,1 1,-1.413 -1.4A1.4,1.4 0,0 1,52.026 159.426Z"
android:fillColor="#fede0d"/>
<path
android:pathData="M51.582,159.733a0.949,0.949 0,1 1,-0.949 -0.949A0.951,0.951 0,0 1,51.582 159.733Z"
android:fillColor="#fbc833"/>
</group>
<group>
<clip-path
android:pathData="M45.851,7.457m-31.932,0a31.932,31.932 0,1 1,63.864 0a31.932,31.932 0,1 1,-63.864 0"/>
<path
android:pathData="M56.791,43.928H31.621a94.2,94.2 0,0 1,3.437 -11.6,17.281 17.281,0 0,0 0.7,-3A52.611,52.611 0,0 1,37.3 22.1l0.986,-3.394H51.594l1.973,4.6a35.326,35.326 0,0 1,1.84 5.757q0.134,0.559 0.315,1.107c2.134,6.439 4.152,9.21 4.358,13.76Z"
android:fillColor="#4caef6"/>
<path
android:pathData="M57.235,-0.142l-0.054,-0.446a0.861,0.861 0,0 0,-1.334 -0.665L53.129,0.274a23.951,23.951 0,0 0,-4.5 3.291l-0.869,0.8H43.143l-0.868,-0.8A23.957,23.957 0,0 0,37.77 0.274L35.053,-1.253a0.862,0.862 0,0 0,-1.335 0.665l-0.053,0.446A32.239,32.239 0,0 0,34.158 10.3l0.087,0.417a1.343,1.343 0,0 0,0.163 0.416,3.865 3.865,0 0,1 0.492,1.991V16.7A10.185,10.185 0,0 0,45.085 26.886h0.572A10.186,10.186 0,0 0,55.843 16.7v-3a4.9,4.9 0,0 1,0.641 -2.557,1.345 1.345,0 0,0 0.171,-0.43l0.087,-0.417A32.267,32.267 0,0 0,57.235 -0.142Z"
android:fillColor="#c3e2fc"/>
<path
android:pathData="M38.285,43.816a20.469,20.469 0,0 0,0.613 -5.071h0c-0.016,-4.1 2.515,-7.427 5.643,-7.427h2.113c2.969,0 5.431,3.014 5.63,6.894l0.028,0.526a44.9,44.9 0,0 0,0.955 5.19"
android:fillColor="#e7f4fd"/>
<path
android:pathData="M44.16,10.873l-0.529,4.3a3.619,3.619 0,0 1,-1.763 2.608,5.053 5.053,0 0,0 -2.543,4.263v1.54a4.01,4.01 0,0 0,4.267 3.691h3.559a4.01,4.01 0,0 0,4.266 -3.691v-1.54a5.052,5.052 0,0 0,-2.54 -4.261,3.717 3.717,0 0,1 -1.842,-2.759l-0.409,-4.216A1.235,1.235 0,0 0,44.16 10.873Z"
android:fillColor="#e7f4fd"/>
<path
android:pathData="M44.832,18.893H45.91a1.172,1.172 0,0 1,1.172 1.172v0a1.607,1.607 0,0 1,-1.607 1.607h-0.208a1.607,1.607 0,0 1,-1.607 -1.607v0A1.172,1.172 0,0 1,44.832 18.893Z"
android:fillColor="#4caef6"/>
<path
android:pathData="M48.658,14.525a1.405,1.457 0,1 0,2.81 0a1.405,1.457 0,1 0,-2.81 0z"
android:fillColor="#4caef6"/>
<path
android:pathData="M49.291,14.911a0.772,0.801 0,1 0,1.544 0a0.772,0.801 0,1 0,-1.544 0z"
android:fillColor="#2293e8"/>
<path
android:pathData="M38.499,14.525a1.405,1.457 0,1 0,2.81 0a1.405,1.457 0,1 0,-2.81 0z"
android:fillColor="#4caef6"/>
<path
android:pathData="M39.076,14.969a0.828,0.86 0,1 0,1.656 0a0.828,0.86 0,1 0,-1.656 0z"
android:fillColor="#2293e8"/>
<path
android:pathData="M46.4,25.99c-0.888,-0.179 -0.891,-0.586 -0.891,-0.586l-0.145,-5.614 -0.113,5.617s0,0.405 -0.883,0.595a4.655,4.655 0,0 1,-3 -1.161,4.817 4.817,0 0,0 3,1.53s0.554,0.118 1.012,-0.595c0.466,0.707 1.019,0.583 1.019,0.583a4.821,4.821 0,0 0,2.98 -1.57A4.664,4.664 0,0 1,46.4 25.99Z"
android:fillColor="#4caef6"/>
<path
android:pathData="M49.227,6.259h0a0.775,0.775 0,0 1,0.008 -1.215l0.213,-0.2A21.968,21.968 0,0 1,55.367 0.906l0.279,-0.125a0.587,0.587 0,0 1,0.855 0.547l0.06,2.12a16.34,16.34 0,0 1,-0.344 3.78l-0.355,1.7a0.781,0.781 0,0 1,-1.07 0.625l-0.143,-0.161A9.917,9.917 0,0 0,49.227 6.259Z"
android:fillColor="#4caef6"/>
<path
android:pathData="M41.531,5.905h0a0.735,0.735 0,0 0,-0.007 -1.153l-0.2,-0.187A20.845,20.845 0,0 0,35.7 0.824L35.439,0.706a0.556,0.556 0,0 0,-0.812 0.518L34.57,3.237A15.5,15.5 0,0 0,34.9 6.825l0.337,1.615a0.741,0.741 0,0 0,1.015 0.593l0.135,-0.152A9.417,9.417 0,0 1,41.531 5.905Z"
android:fillColor="#4caef6"/>
</group>
</group>
</group>
</vector>

Двоичные данные
app/src/main/res/drawable/leroy.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 301 KiB

Двоичные данные
app/src/main/res/drawable/nox.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 46 KiB

Двоичные данные
app/src/main/res/drawable/tzeitel.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 154 KiB

Двоичные данные
app/src/main/res/layout/._activity_grid_list.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/layout/._activity_horizontal_list.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/layout/._activity_main.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/layout/._activity_vertical_list.xml Normal file

Двоичный файл не отображается.

Двоичные данные
app/src/main/res/layout/._grid_list_item.xml Normal file

Двоичный файл не отображается.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше