diff --git a/app-catalog/samples/wBasis/build.gradle b/app-catalog/samples/wBasis/build.gradle index 3860e29..2a1e011 100644 --- a/app-catalog/samples/wBasis/build.gradle +++ b/app-catalog/samples/wBasis/build.gradle @@ -1,3 +1,19 @@ +/* + * Copyright 2023-2025 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. + */ + apply from: "$rootDir/gradle/sample-build.gradle" apply plugin: 'kotlin-parcelize' @@ -9,6 +25,8 @@ android { res.srcDirs( 'src/main/res', 'src/main/res-ext', + 'src/main/res-gesture', + 'src/main/res-transition', ) } } diff --git a/app-catalog/samples/wBasis/libwBasis/build.gradle b/app-catalog/samples/wBasis/libwBasis/build.gradle index 67af3e9..251c0ab 100644 --- a/app-catalog/samples/wBasis/libwBasis/build.gradle +++ b/app-catalog/samples/wBasis/libwBasis/build.gradle @@ -1,3 +1,19 @@ +/* + * Copyright 2023-2025 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. + */ + apply from: "$rootDir/gradle/sample-build.gradle" android { diff --git a/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/activities/SampleActivityBase.java b/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/activities/SampleActivityBase.java new file mode 100644 index 0000000..d199eac --- /dev/null +++ b/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/activities/SampleActivityBase.java @@ -0,0 +1,48 @@ +/* + * Copyright 2023-2025 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 lib.wintmain.wBasis.activities; + +import android.os.Bundle; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import lib.wintmain.wBasis.logger.Log; +import lib.wintmain.wBasis.logger.LogWrapper; + +public class SampleActivityBase extends FragmentActivity { + public final static String TAG = SampleActivityBase.class.getSimpleName(); + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + protected void onStart() { + super.onStart(); + initializeLogging(); + } + + /** Set up targets to receive log data */ + public void initializeLogging() { + // Using Log, front-end to the logging chain, emulates android.util.log method signatures. + // Wraps Android's native log framework + LogWrapper logWrapper = new LogWrapper(); + Log.setLogNode(logWrapper); + + Log.i(TAG, "Ready"); + } +} diff --git a/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/view/SlidingTabLayout.java b/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/view/SlidingTabLayout.java new file mode 100644 index 0000000..f8117c0 --- /dev/null +++ b/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/view/SlidingTabLayout.java @@ -0,0 +1,307 @@ +/* + * Copyright 2023-2025 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 lib.wintmain.wBasis.view; + +import android.content.Context; +import android.graphics.Typeface; +import android.os.Build; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.HorizontalScrollView; +import android.widget.TextView; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; + +/** + * To be used with ViewPager to provide a tab indicator component which give constant feedback as to + * the user's scroll progress. + *
+ * To use the component, simply add it to your view hierarchy. Then in your + * {@link android.app.Activity} or {@link Fragment} call + * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for. + *
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors + * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The + * alternative is via the {@link TabColorizer} interface which provides you complete control over + * which color is used for any individual position. + *
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+ private static final int TITLE_OFFSET_DIPS = 24;
+ private static final int TAB_VIEW_PADDING_DIPS = 16;
+ private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+ private final int mTitleOffset;
+ private final SlidingTabStrip mTabStrip;
+ private int mTabViewLayoutId;
+ private int mTabViewTextViewId;
+ private ViewPager mViewPager;
+ private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+ public SlidingTabLayout(Context context) {
+ this(context, null);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ // Disable the Scroll Bar & Make sure that the Tab Strips fills this View
+ setHorizontalScrollBarEnabled(false);
+ setFillViewport(true);
+
+ mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+ mTabStrip = new SlidingTabStrip(context);
+ addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ /**
+ * Set the custom {@link TabColorizer} to be used.
+ *
+ * If you only require simple custmisation then you can use
+ * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+ * similar effects.
+ */
+ public void setCustomTabColorizer(TabColorizer tabColorizer) {
+ mTabStrip.setCustomTabColorizer(tabColorizer);
+ }
+
+ /**
+ * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+ * circular array. Providing one color will mean that all tabs are indicated with the same
+ * color.
+ */
+ public void setSelectedIndicatorColors(int... colors) {
+ mTabStrip.setSelectedIndicatorColors(colors);
+ }
+
+ /**
+ * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+ * Providing one color will mean that all tabs are indicated with the same color.
+ */
+ public void setDividerColors(int... colors) {
+ mTabStrip.setDividerColors(colors);
+ }
+
+ /**
+ * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+ * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+ * that the layout can update it's scroll position correctly.
+ *
+ * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+ */
+ public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+ mViewPagerPageChangeListener = listener;
+ }
+
+ /**
+ * Set the custom layout to be inflated for the tab views.
+ *
+ * @param layoutResId Layout id to be inflated
+ * @param textViewId id of the {@link TextView} in the inflated view
+ */
+ public void setCustomTabView(int layoutResId, int textViewId) {
+ mTabViewLayoutId = layoutResId;
+ mTabViewTextViewId = textViewId;
+ }
+
+ /**
+ * Sets the associated view pager. Note that the assumption here is that the pager content
+ * (number of tabs and tab titles) does not change after this call has been made.
+ */
+ public void setViewPager(ViewPager viewPager) {
+ mTabStrip.removeAllViews();
+
+ mViewPager = viewPager;
+ if (viewPager != null) {
+ viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+ populateTabStrip();
+ }
+ }
+
+ /**
+ * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+ * {@link #setCustomTabView(int, int)}.
+ */
+ protected TextView createDefaultTabView(Context context) {
+ TextView textView = new TextView(context);
+ textView.setGravity(Gravity.CENTER);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+ textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // If we're running on Honeycomb or newer, then we can use the Theme's
+ // selectableItemBackground to ensure that the View has a pressed state
+ TypedValue outValue = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+ outValue, true);
+ textView.setBackgroundResource(outValue.resourceId);
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+ textView.setAllCaps(true);
+ }
+
+ int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+ textView.setPadding(padding, padding, padding, padding);
+
+ return textView;
+ }
+
+ private void populateTabStrip() {
+ final PagerAdapter adapter = mViewPager.getAdapter();
+ final View.OnClickListener tabClickListener = new TabClickListener();
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View tabView = null;
+ TextView tabTitleView = null;
+
+ if (mTabViewLayoutId != 0) {
+ // If there is a custom tab view layout id set, try and inflate it
+ tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+ false);
+ tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+ }
+
+ if (tabView == null) {
+ tabView = createDefaultTabView(getContext());
+ }
+
+ if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+ tabTitleView = (TextView) tabView;
+ }
+
+ tabTitleView.setText(adapter.getPageTitle(i));
+ tabView.setOnClickListener(tabClickListener);
+
+ mTabStrip.addView(tabView);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (mViewPager != null) {
+ scrollToTab(mViewPager.getCurrentItem(), 0);
+ }
+ }
+
+ private void scrollToTab(int tabIndex, int positionOffset) {
+ final int tabStripChildCount = mTabStrip.getChildCount();
+ if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+ return;
+ }
+
+ View selectedChild = mTabStrip.getChildAt(tabIndex);
+ if (selectedChild != null) {
+ int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+ if (tabIndex > 0 || positionOffset > 0) {
+ // If we're not at the first child and are mid-scroll, make sure we obey the offset
+ targetScrollX -= mTitleOffset;
+ }
+
+ scrollTo(targetScrollX, 0);
+ }
+ }
+
+ /**
+ * Allows complete control over the colors drawn in the tab layout. Set with
+ * {@link #setCustomTabColorizer(TabColorizer)}.
+ */
+ public interface TabColorizer {
+
+ /**
+ * @return return the color of the indicator used when {@code position} is selected.
+ */
+ int getIndicatorColor(int position);
+
+ /**
+ * @return return the color of the divider drawn to the right of {@code position}.
+ */
+ int getDividerColor(int position);
+
+ }
+
+ private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+ private int mScrollState;
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ int tabStripChildCount = mTabStrip.getChildCount();
+ if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+ return;
+ }
+
+ mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+ View selectedTitle = mTabStrip.getChildAt(position);
+ int extraOffset = (selectedTitle != null)
+ ? (int) (positionOffset * selectedTitle.getWidth())
+ : 0;
+ scrollToTab(position, extraOffset);
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+ positionOffsetPixels);
+ }
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ mScrollState = state;
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+ }
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+ mTabStrip.onViewPagerPageChanged(position, 0f);
+ scrollToTab(position, 0);
+ }
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageSelected(position);
+ }
+ }
+ }
+
+ private class TabClickListener implements View.OnClickListener {
+ @Override
+ public void onClick(View v) {
+ for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+ if (v == mTabStrip.getChildAt(i)) {
+ mViewPager.setCurrentItem(i);
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/view/SlidingTabStrip.java b/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/view/SlidingTabStrip.java
new file mode 100644
index 0000000..6defc82
--- /dev/null
+++ b/app-catalog/samples/wBasis/libwBasis/src/main/java/lib/wintmain/wBasis/view/SlidingTabStrip.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2023-2025 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 lib.wintmain.wBasis.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+import androidx.annotation.Nullable;
+
+public class SlidingTabStrip extends LinearLayout {
+ private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+ private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+ private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+ private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+ private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+ private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+ private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+ private final SimpleTabColorizer mDefaultTabColorizer;
+ private final int mBottomBorderThickness;
+ private final Paint mBottomBorderPaint;
+ private final int mSelectedIndicatorThickness;
+ private final Paint mSelectedIndicatorPaint;
+ private final Paint mDividerPaint;
+ private final float mDividerHeight;
+ private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+ private int mSelectedPosition;
+ private float mSelectionOffset;
+
+ public SlidingTabStrip(Context context) {
+ this(context, null);
+ }
+
+ public SlidingTabStrip(Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ setWillNotDraw(false);
+
+ final float density = getResources().getDisplayMetrics().density;
+
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true);
+ final int themeForegroundColor = outValue.data;
+
+ int mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+ DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+ mDefaultTabColorizer = new SimpleTabColorizer();
+ mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+ mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+ DEFAULT_DIVIDER_COLOR_ALPHA));
+
+ mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+ mBottomBorderPaint = new Paint();
+ mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+ mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+ mSelectedIndicatorPaint = new Paint();
+
+ mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+ mDividerPaint = new Paint();
+ mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+ }
+
+ /**
+ * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+ */
+ private static int setColorAlpha(int color, byte alpha) {
+ return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+ }
+
+ /**
+ * Blend {@code color1} and {@code color2} using the given ratio.
+ *
+ * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+ * 0.0 will return {@code color2}.
+ */
+ private static int blendColors(int color1, int color2, float ratio) {
+ final float inverseRation = 1f - ratio;
+ float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+ float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+ float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+ return Color.rgb((int) r, (int) g, (int) b);
+ }
+
+ void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+ mCustomTabColorizer = customTabColorizer;
+ invalidate();
+ }
+
+ void setSelectedIndicatorColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setIndicatorColors(colors);
+ invalidate();
+ }
+
+ void setDividerColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setDividerColors(colors);
+ invalidate();
+ }
+
+ void onViewPagerPageChanged(int position, float positionOffset) {
+ mSelectedPosition = position;
+ mSelectionOffset = positionOffset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ final int height = getHeight();
+ final int childCount = getChildCount();
+ final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+ final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+ ? mCustomTabColorizer
+ : mDefaultTabColorizer;
+
+ // Thick colored underline below the current selection
+ if (childCount > 0) {
+ View selectedTitle = getChildAt(mSelectedPosition);
+ int left = selectedTitle.getLeft();
+ int right = selectedTitle.getRight();
+ int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+ if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+ int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+ if (color != nextColor) {
+ color = blendColors(nextColor, color, mSelectionOffset);
+ }
+
+ // Draw the selection partway between the tabs
+ View nextTitle = getChildAt(mSelectedPosition + 1);
+ left = (int) (mSelectionOffset * nextTitle.getLeft() +
+ (1.0f - mSelectionOffset) * left);
+ right = (int) (mSelectionOffset * nextTitle.getRight() +
+ (1.0f - mSelectionOffset) * right);
+ }
+
+ mSelectedIndicatorPaint.setColor(color);
+
+ canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+ height, mSelectedIndicatorPaint);
+ }
+
+ // Thin underline along the entire bottom edge
+ canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+ // Vertical separators between the titles
+ int separatorTop = (height - dividerHeightPx) / 2;
+ for (int i = 0; i < childCount - 1; i++) {
+ View child = getChildAt(i);
+ mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+ canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+ separatorTop + dividerHeightPx, mDividerPaint);
+ }
+ }
+
+ private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+ private int[] mIndicatorColors;
+ private int[] mDividerColors;
+
+ @Override
+ public final int getIndicatorColor(int position) {
+ return mIndicatorColors[position % mIndicatorColors.length];
+ }
+
+ @Override
+ public final int getDividerColor(int position) {
+ return mDividerColors[position % mDividerColors.length];
+ }
+
+ void setIndicatorColors(int... colors) {
+ mIndicatorColors = colors;
+ }
+
+ void setDividerColors(int... colors) {
+ mDividerColors = colors;
+ }
+ }
+}
diff --git a/app-catalog/samples/wBasis/src/main/AndroidManifest.xml b/app-catalog/samples/wBasis/src/main/AndroidManifest.xml
index 14a79b4..883c0c2 100644
--- a/app-catalog/samples/wBasis/src/main/AndroidManifest.xml
+++ b/app-catalog/samples/wBasis/src/main/AndroidManifest.xml
@@ -1,5 +1,4 @@
-
-
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+@Sample(name = "BasicTransition",
+ description = "基础的变化",
+ tags = {"android-samples", "animation-samples"}
+)
+public class BasicTransitionActivity extends AppCompatActivity {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_basic_transition);
+
+ if (savedInstanceState == null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ BasicTransitionFragment fragment = new BasicTransitionFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ @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(mLogShown ? 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) {
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ // Set up targets to receive log data
+
+ /** Create a chain of targets that will receive log data */
+ public void initializeLogging() {
+ // 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");
+ }
+}
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/BasicTransitionFragment.java b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/BasicTransitionFragment.java
new file mode 100644
index 0000000..b965d06
--- /dev/null
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/BasicTransitionFragment.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2023-2025 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.transition;
+
+import android.os.Bundle;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.RadioGroup;
+import androidx.fragment.app.Fragment;
+import com.wintmain.wBasis.R;
+import lib.wintmain.wBasis.logger.Log;
+
+public class BasicTransitionFragment extends Fragment
+ implements RadioGroup.OnCheckedChangeListener {
+
+ // We transition between these Scenes
+ private Scene mScene1;
+ private Scene mScene2;
+ private Scene mScene3;
+
+ /** A custom TransitionManager */
+ private TransitionManager mTransitionManagerForScene3;
+
+ /** Transitions take place in this ViewGroup. We retain this for the dynamic transition on
+ * scene 4. */
+ private ViewGroup mSceneRoot;
+
+ public BasicTransitionFragment() {
+ }
+
+ public static BasicTransitionFragment newInstance() {
+ return new BasicTransitionFragment();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_basic_transition, container, false);
+ assert view != null;
+ RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.select_scene);
+ radioGroup.setOnCheckedChangeListener(this);
+ mSceneRoot = (ViewGroup) view.findViewById(R.id.scene_root);
+
+ // BEGIN_INCLUDE(instantiation_from_view)
+ // A Scene can be instantiated from a live view hierarchy.
+ mScene1 = new Scene(mSceneRoot, (ViewGroup) mSceneRoot.findViewById(R.id.container));
+ // END_INCLUDE(instantiation_from_view)
+
+ // BEGIN_INCLUDE(instantiation_from_resource)
+ // You can also inflate a generate a Scene from a layout resource file.
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, getActivity());
+ // END_INCLUDE(instantiation_from_resource)
+
+ // Another scene from a layout resource file.
+ mScene3 = Scene.getSceneForLayout(mSceneRoot, R.layout.scene3, getActivity());
+
+ // BEGIN_INCLUDE(custom_transition_manager)
+ // We create a custom TransitionManager for Scene 3, in which ChangeBounds and Fade
+ // take place at the same time.
+ mTransitionManagerForScene3 = TransitionInflater.from(getActivity())
+ .inflateTransitionManager(R.transition.scene3_transition_manager, mSceneRoot);
+ // END_INCLUDE(custom_transition_manager)
+
+ return view;
+ }
+
+ @Override
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ if (checkedId == R.id.select_scene_1) {
+ // BEGIN_INCLUDE(transition_simple)
+ // You can start an automatic transition with TransitionManager.go().
+ TransitionManager.go(mScene1);
+ Log.d(BasicTransitionActivity.TAG, "select 1");
+ // END_INCLUDE(transition_simple)
+ } else if (checkedId == R.id.select_scene_2) {
+ TransitionManager.go(mScene2);
+ Log.d(BasicTransitionActivity.TAG, "select 2");
+ } else if (checkedId == R.id.select_scene_3) {
+ // BEGIN_INCLUDE(transition_custom)
+ // You can also start a transition with a custom TransitionManager.
+ mTransitionManagerForScene3.transitionTo(mScene3);
+ Log.d(BasicTransitionActivity.TAG, "select 3");
+ // END_INCLUDE(transition_custom)
+ } else if (checkedId == R.id.select_scene_4) {
+ // BEGIN_INCLUDE(transition_dynamic)
+ // Alternatively, transition can be invoked dynamically without a Scene.
+ // For this, we first call TransitionManager.beginDelayedTransition().
+ TransitionManager.beginDelayedTransition(mSceneRoot);
+ // Then, we can just change view properties as usual.
+ View square = mSceneRoot.findViewById(R.id.transition_square);
+ ViewGroup.LayoutParams params = square.getLayoutParams();
+ int newSize = getResources().getDimensionPixelSize(R.dimen.square_size_expanded);
+ params.width = newSize;
+ params.height = newSize;
+ square.setLayoutParams(params);
+ Log.d(BasicTransitionActivity.TAG, "select 4");
+ // END_INCLUDE(transition_dynamic)
+ }
+ }
+}
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/CustomTransitionActivity.java b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/CustomTransitionActivity.java
new file mode 100644
index 0000000..80f9e86
--- /dev/null
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/CustomTransitionActivity.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2023-2025 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.transition;
+
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+import android.widget.ViewAnimator;
+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 = "CustomTransition",
+ description = "自定义的变化",
+ tags = {"android-samples", "animation-samples"}
+)
+public class CustomTransitionActivity extends AppCompatActivity {
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_custom_transition);
+
+ if (savedInstanceState == null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ CustomTransitionFragment fragment = new CustomTransitionFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ // Set up targets to receive log data
+
+ /** Create a chain of targets that will receive log data */
+ public void initializeLogging() {
+ // 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(mLogShown ? 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) {
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ } else if (item.getItemId() == R.id.clear_action) {
+ TextView tv = (TextView) findViewById(R.id.custom_clear_tv);
+ tv.setText("");
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/CustomTransitionFragment.java b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/CustomTransitionFragment.java
new file mode 100644
index 0000000..404716b
--- /dev/null
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/CustomTransitionFragment.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2023-2025 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.transition;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import com.wintmain.wBasis.R;
+import com.wintmain.wBasis.transition.util.ChangeColor;
+import lib.wintmain.wBasis.logger.Log;
+
+public class CustomTransitionFragment extends Fragment implements View.OnClickListener {
+ private static final String TAG = CustomTransitionFragment.class.getSimpleName();
+
+ private static final String STATE_CURRENT_SCENE = "current_scene";
+
+ /** These are the Scenes we use. */
+ private Scene[] mScenes;
+
+ /** The current index for mScenes. */
+ private int mCurrentScene;
+ /** This is the custom Transition we use in this sample. */
+ private Transition mTransition;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_custom_transition, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ Context context = getActivity();
+ FrameLayout container = (FrameLayout) view.findViewById(R.id.container);
+ view.findViewById(R.id.show_next_scene).setOnClickListener(this);
+ if (null != savedInstanceState) {
+ mCurrentScene = savedInstanceState.getInt(STATE_CURRENT_SCENE);
+ }
+ // We set up the Scenes here.
+ mScenes = new Scene[]{
+ Scene.getSceneForLayout(container, R.layout.custom_scene1, context),
+ Scene.getSceneForLayout(container, R.layout.custom_scene2, context),
+ Scene.getSceneForLayout(container, R.layout.custom_scene3, context),
+ };
+ // This is the custom Transition.
+ mTransition = new ChangeColor();
+ // Show the initial Scene.
+ TransitionManager.go(mScenes[mCurrentScene % mScenes.length]);
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_CURRENT_SCENE, mCurrentScene);
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.show_next_scene) {
+ mCurrentScene = (mCurrentScene + 1) % mScenes.length;
+ Log.i(TAG, "Transitioning to scene #" + mCurrentScene);
+ // Pass the custom Transition as second argument for TransitionManager.go
+ TransitionManager.go(mScenes[mCurrentScene], mTransition);
+ }
+ }
+}
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/util/ChangeColor.java b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/util/ChangeColor.java
new file mode 100644
index 0000000..b09f29a
--- /dev/null
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/transition/util/ChangeColor.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2023-2025 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.transition.util;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.view.View;
+import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+
+public class ChangeColor extends Transition {
+ /** Key to store a color value in TransitionValues object */
+ private static final String PROPNAME_BACKGROUND = "customtransition:change_color:background";
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ // Capture the value of the background drawable property for a target in the ending Scene.
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ // BEGIN_INCLUDE (capture_values)
+
+ /**
+ * Convenience method: Add the background Drawable property value
+ * to the TransitionsValues.value Map for a target.
+ */
+ private void captureValues(TransitionValues values) {
+ // Capture the property values of views for later use
+ values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
+ }
+ // END_INCLUDE (capture_values)
+
+ // BEGIN_INCLUDE (create_animator)
+ // Create an animation for each target that is in both the starting and ending Scene. For each
+ // pair of targets, if their background property value is a color (rather than a graphic),
+ // create a ValueAnimator based on an ArgbEvaluator that interpolates between the starting and
+ // ending color. Also create an update listener that sets the View background color for each
+ // animation frame
+ @Override
+ public Animator createAnimator(@NonNull ViewGroup sceneRoot,
+ TransitionValues startValues, TransitionValues endValues) {
+ // This transition can only be applied to views that are on both starting and ending scenes.
+ if (null == startValues || null == endValues) {
+ return null;
+ }
+ // Store a convenient reference to the target. Both the starting and ending layout have the
+ // same target.
+ final View view = endValues.view;
+ // Store the object containing the background property for both the starting and ending
+ // layouts.
+ Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
+ Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
+ // This transition changes background colors for a target. It doesn't animate any other
+ // background changes. If the property isn't a ColorDrawable, ignore the target.
+ if (startBackground instanceof ColorDrawable startColor
+ && endBackground instanceof ColorDrawable endColor) {
+ // If the background color for the target in the starting and ending layouts is
+ // different, create an animation.
+ if (startColor.getColor() != endColor.getColor()) {
+ // Create a new Animator object to apply to the targets as the transitions framework
+ // changes from the starting to the ending layout. Use the class ValueAnimator,
+ // which provides a timing pulse to change property values provided to it. The
+ // animation runs on the UI thread. The Evaluator controls what type of
+ // interpolation is done. In this case, an ArgbEvaluator interpolates between two
+ // #argb values, which are specified as the 2nd and 3rd input arguments.
+ ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),
+ startColor.getColor(), endColor.getColor());
+ // Add an update listener to the Animator object.
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ Object value = animation.getAnimatedValue();
+ // Each time the ValueAnimator produces a new frame in the animation, change
+ // the background color of the target. Ensure that the value isn't null.
+ if (null != value) {
+ view.setBackgroundColor((Integer) value);
+ }
+ }
+ });
+ // Return the Animator object to the transitions framework. As the framework changes
+ // between the starting and ending layouts, it applies the animation you've created.
+ return animator;
+ }
+ }
+ // For non-ColorDrawable backgrounds, we just return null, and no animation will take place.
+ return null;
+ }
+ // END_INCLUDE (create_animator)
+}
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/ConstraintLayout.kt b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/ConstraintLayout.kt
similarity index 99%
rename from app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/ConstraintLayout.kt
rename to app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/ConstraintLayout.kt
index 5616b91..16d6838 100644
--- a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/ConstraintLayout.kt
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/ConstraintLayout.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.wintmain.wBasis.ui.views.layout
+package com.wintmain.wBasis.ui.layout
import android.os.Bundle
import android.view.View
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/NewsDetailsFragment.kt b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/NewsDetailsFragment.kt
similarity index 96%
rename from app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/NewsDetailsFragment.kt
rename to app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/NewsDetailsFragment.kt
index 626609e..afa1919 100644
--- a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/NewsDetailsFragment.kt
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/NewsDetailsFragment.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.wintmain.wBasis.ui.views.layout.slidingpanelayout
+package com.wintmain.wBasis.ui.layout.slidingpanelayout
import android.os.Bundle
import android.view.LayoutInflater
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/SlidingPaneLayoutMain.kt b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/SlidingPaneLayoutMain.kt
similarity index 92%
rename from app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/SlidingPaneLayoutMain.kt
rename to app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/SlidingPaneLayoutMain.kt
index 04245b9..c1646bc 100644
--- a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/SlidingPaneLayoutMain.kt
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/SlidingPaneLayoutMain.kt
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package com.wintmain.wBasis.ui.views.layout.slidingpanelayout
+package com.wintmain.wBasis.ui.layout.slidingpanelayout
import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
@@ -39,7 +38,7 @@ import com.wintmain.wBasis.databinding.SlidingPanelMainBinding
documentation = "",
tags = ["android-samples", "layout"],
)
-class SlidingPaneLayoutMain : AppCompatActivity() {
+class SlidingPaneLayoutMain : androidx.appcompat.app.AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
@@ -61,5 +60,4 @@ class SlidingPaneLayoutMain : AppCompatActivity() {
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
-
}
\ No newline at end of file
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/Sport.kt b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/Sport.kt
similarity index 93%
rename from app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/Sport.kt
rename to app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/Sport.kt
index 2f0a049..e25c177 100644
--- a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/Sport.kt
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/Sport.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.wintmain.wBasis.ui.views.layout.slidingpanelayout
+package com.wintmain.wBasis.ui.layout.slidingpanelayout
import com.wintmain.wBasis.R
diff --git a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/SportsAdapter.kt b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/SportsAdapter.kt
similarity index 89%
rename from app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/SportsAdapter.kt
rename to app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/SportsAdapter.kt
index 561daa0..e20c5f0 100644
--- a/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/views/layout/slidingpanelayout/SportsAdapter.kt
+++ b/app-catalog/samples/wBasis/src/main/java/com/wintmain/wBasis/ui/layout/slidingpanelayout/SportsAdapter.kt
@@ -14,27 +14,26 @@
* limitations under the License.
*/
-package com.wintmain.wBasis.ui.views.layout.slidingpanelayout
+package com.wintmain.wBasis.ui.layout.slidingpanelayout
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.wintmain.wBasis.databinding.SportsListItemBinding
-import com.wintmain.wBasis.ui.views.layout.slidingpanelayout.SportsAdapter.SportsViewHolder
+import com.wintmain.wBasis.ui.layout.slidingpanelayout.SportsAdapter.SportsViewHolder
class SportsAdapter(private val onItemClicked: (Sport) -> Unit) :
- ListAdapter