diff --git a/app-catalog/app/build.gradle b/app-catalog/app/build.gradle index 6c8cc48..0bee008 100644 --- a/app-catalog/app/build.gradle +++ b/app-catalog/app/build.gradle @@ -1,6 +1,6 @@ /* * Copyright 2022 Google LLC - * Copyright 2023-2025 wintmain + * Copyright 2023-2026 wintmain * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ plugins { id 'org.jetbrains.kotlin.android' id 'com.google.devtools.ksp' id 'dagger.hilt.android.plugin' + id 'org.jetbrains.kotlin.plugin.compose' } android { @@ -35,8 +36,8 @@ android { applicationId "com.wintmain.catalog.app" minSdk 26 targetSdk 34 - versionCode 20250601 - versionName 'V20250601' + versionCode 20260207 + versionName 'V20260207' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -59,9 +60,11 @@ android { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } - composeOptions { - kotlinCompilerExtensionVersion libs.versions.composeCompiler.get() - } + + // Compose Compiler plugin replaces composeOptions + // composeOptions { + // kotlinCompilerExtensionVersion libs.versions.composeCompiler.get() + // } lint { checkReleaseBuilds false diff --git a/app-catalog/samples/wBasis/build.gradle b/app-catalog/samples/wBasis/build.gradle index b22e42b..fc61165 100644 --- a/app-catalog/samples/wBasis/build.gradle +++ b/app-catalog/samples/wBasis/build.gradle @@ -24,6 +24,7 @@ android { // res 资源目录配置 res.srcDirs( 'src/main/res', + 'src/main/res-animation', 'src/main/res-ext', 'src/main/res-gesture', 'src/main/res-transition', diff --git a/app-catalog/samples/wBasis/src/main/AndroidManifest.xml b/app-catalog/samples/wBasis/src/main/AndroidManifest.xml index 20f1063..ddd4829 100644 --- a/app-catalog/samples/wBasis/src/main/AndroidManifest.xml +++ b/app-catalog/samples/wBasis/src/main/AndroidManifest.xml @@ -391,6 +391,11 @@ android:name=".transition.GridToPagerMainActivity" android:exported="true" android:theme="@style/GridToPager_Activity_Theme" /> + + \ No newline at end of file diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/animation/RevealEffectBasicActivity.java b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/animation/RevealEffectBasicActivity.java new file mode 100644 index 0000000..88667b7 --- /dev/null +++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/animation/RevealEffectBasicActivity.java @@ -0,0 +1,101 @@ +/* + * Copyright 2023-2026 wintmain + * + * 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 + * + * https://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.wintmain.wBasis.animation; + +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ViewAnimator; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.FragmentTransaction; +import com.google.android.catalog.framework.annotations.Sample; +import com.wintmain.wBasis.R; +import lib.wintmain.wBasis.logger.Log; +import lib.wintmain.wBasis.logger.LogFragment; +import lib.wintmain.wBasis.logger.LogWrapper; +import lib.wintmain.wBasis.logger.MessageOnlyLogFilter; + + +@Sample(name = "RevealEffectBasicActivity", + description = "揭露动画,一种类似于水波纹效果的从一个点向周围扩散或者从四周向一个点集中的动画效果", + tags = {"android-samples", "animation-samples"} +) +public class RevealEffectBasicActivity extends AppCompatActivity { + public static final String TAG = "RevealEffectBasicActivity"; + private boolean isLogShow = false; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_reveal_effect); + + if (savedInstanceState == null) { + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + RevealEffectBasicFragment fragment = new RevealEffectBasicFragment(); + transaction.replace(R.id.sample_content_fragment, fragment); + transaction.commit(); + } + + // Wraps Android's native log framework. + LogWrapper logWrapper = new LogWrapper(); + // Using Log, front-end to the logging chain, emulates android.util.log method signatures. + Log.setLogNode(logWrapper); + + // Filter strips out everything except the message text. + MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter(); + logWrapper.setNext(msgFilter); + + // On screen logging via a fragment with a TextView. + LogFragment logFragment = (LogFragment) getSupportFragmentManager() + .findFragmentById(R.id.log_fragment); + msgFilter.setNext(logFragment.getLogView()); + + Log.i(TAG, "Ready"); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + MenuItem logToggle = menu.findItem(R.id.menu_toggle_log); + logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator); + logToggle.setTitle(isLogShow ? R.string.sample_hide_log : R.string.sample_show_log); + + return super.onPrepareOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.menu_toggle_log) { + isLogShow = !isLogShow; + ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output); + if (isLogShow) { + output.setDisplayedChild(1); + } else { + output.setDisplayedChild(0); + } + invalidateOptionsMenu(); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/animation/RevealEffectBasicFragment.java b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/animation/RevealEffectBasicFragment.java new file mode 100644 index 0000000..c800508 --- /dev/null +++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/animation/RevealEffectBasicFragment.java @@ -0,0 +1,70 @@ +/* + * Copyright 2023-2026 wintmain + * + * 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 + * + * https://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.wintmain.wBasis.animation; + +import android.animation.Animator; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewAnimationUtils; +import android.view.ViewGroup; +import android.view.animation.AccelerateDecelerateInterpolator; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import com.wintmain.wBasis.R; +import lib.wintmain.wBasis.logger.Log; + +/** + * This sample shows a view that is revealed when a button is clicked. + */ +public class RevealEffectBasicFragment extends Fragment { + private final static String TAG = "RevealEffectBasicFragment"; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_reveal_effect, container, false); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + View circle = view.findViewById(R.id.circle); + View button = view.findViewById(R.id.button); + + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Create a reveal {@link Animator} that starts clipping the view from + // the top left corner until the whole view is covered. + Animator circularReveal = ViewAnimationUtils.createCircularReveal(circle, 0, 0, 0, + (float) Math.hypot(circle.getWidth(), circle.getHeight())); + circularReveal.setInterpolator(new AccelerateDecelerateInterpolator()); + + // Finally start the animation + circularReveal.start(); + + Log.d(TAG, "Starting Reveal animation"); + } + }); + super.onViewCreated(view, savedInstanceState); + } +} diff --git a/app-catalog/samples/wBasis/src/main/res-animation/layout/activity_reveal_effect.xml b/app-catalog/samples/wBasis/src/main/res-animation/layout/activity_reveal_effect.xml new file mode 100644 index 0000000..73d8a1c --- /dev/null +++ b/app-catalog/samples/wBasis/src/main/res-animation/layout/activity_reveal_effect.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app-catalog/samples/wBasis/src/main/res-animation/layout/fragment_reveal_effect.xml b/app-catalog/samples/wBasis/src/main/res-animation/layout/fragment_reveal_effect.xml new file mode 100644 index 0000000..0bdffdf --- /dev/null +++ b/app-catalog/samples/wBasis/src/main/res-animation/layout/fragment_reveal_effect.xml @@ -0,0 +1,44 @@ + + + + + +