Import ExpandableViewLayout from rview

Source: https://github.com/jruesga/rview

Original commits:
    commit c7c72aca0fd3ac74133328efe00d48c5396bf49f
    Author: Jorge Ruesga <jorge@ruesga.com>
    Date:   Fri Aug 24 23:34:15 2018 +0200

        Migrate to androidx

        Signed-off-by: Jorge Ruesga <jorge@ruesga.com>

    commit 2eb2171983afadc25850ed39fcee92c1c160758b
    Author: Jorge Ruesga <jorge@ruesga.com>
    Date:   Sat Jun 10 01:42:42 2017 +0200

        Add support for Android O

        Signed-off-by: Jorge Ruesga <jorge@ruesga.com>

    commit 19906b658f65f7c44ab27bc286a727f17b087b78
    Author: Jorge Ruesga <jorge@ruesga.com>
    Date:   Sat Nov 5 17:35:44 2016 +0100

        Initial collapse commit message if its text rebased 240dp

        Signed-off-by: Jorge Ruesga <jorge@ruesga.com>

Change-Id: I512ab20daf58a884b65e7ef9ba60eecb022de17d
This commit is contained in:
SpiritCroc 2022-11-20 11:04:45 +01:00
parent d636bb3432
commit a9c7c15bd2
4 changed files with 210 additions and 0 deletions

View file

@ -442,6 +442,11 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<br/>
Copyright 2018, Nick / materialdesignicons.com
</li>
<li>
<b>ExpandableViewLayout</b>
<br/>
Copyright (C) 2016 Jorge Ruesga
</li>
<li>
<b>Calling ringtone</b>
<br/>

View file

@ -0,0 +1,164 @@
/*
* Copyright (C) 2016 Jorge Ruesga
*
* 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.ruesga.rview.widget;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.customview.view.AbsSavedState;
import im.vector.app.R;
public class ExpandableViewLayout extends FrameLayout {
private int mMaxHeight;
private boolean mExpanded;
private View mExpandableControl;
private int mChildViewHeight;
public ExpandableViewLayout(Context context) {
this(context, null);
}
public ExpandableViewLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExpandableViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Resources.Theme theme = context.getTheme();
TypedArray a = theme.obtainStyledAttributes(
attrs, R.styleable.ExpandableViewLayout, defStyleAttr, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
if (attr == R.styleable.ExpandableViewLayout_maxHeight) {
mMaxHeight = a.getDimensionPixelSize(attr, mMaxHeight);
} else if (attr == R.styleable.ExpandableViewLayout_expanded) {
mExpanded = a.getBoolean(attr, false);
}
}
a.recycle();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() != 2) {
throw new IllegalStateException(
"ExpandableViewLayout needs 2 views (main view and expandable control view)");
}
// Obtain the expandable control
mExpandableControl = getChildAt(1);
mExpandableControl.setOnClickListener(view -> {
mExpanded = !mExpanded;
setExpandableControlVisibility();
requestLayout();
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Obtain the main view height
View view = getChildAt(0);
view.measure(MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mChildViewHeight = view.getMeasuredHeight();
setExpandableControlVisibility();
// Measure this view according
if (!mExpanded && mMaxHeight > 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void setExpandableControlVisibility() {
final boolean expanded = mExpanded || mMaxHeight == 0 || mMaxHeight > mChildViewHeight;
mExpandableControl.setVisibility(expanded ? View.GONE : View.VISIBLE);
}
@Override
protected Parcelable onSaveInstanceState() {
SavedState savedState = new SavedState(super.onSaveInstanceState());
savedState.mExpanded = mExpanded;
return savedState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
//begin boilerplate code so parent classes can restore state
if(!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
mExpanded = savedState.mExpanded;
setExpandableControlVisibility();
requestLayout();
}
@SuppressWarnings("WeakerAccess")
public static class SavedState extends AbsSavedState {
public boolean mExpanded;
public SavedState(Parcel in, ClassLoader loader) {
super(in, loader);
mExpanded = in.readInt() == 1;
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mExpanded ? 1 : 0);
}
public static final Parcelable.ClassLoaderCreator<SavedState> CREATOR
= new Parcelable.ClassLoaderCreator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel source) {
return createFromParcel(source, null);
}
@Override
public SavedState createFromParcel(Parcel source, ClassLoader loader) {
return new SavedState(source, loader);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 Jorge Ruesga
Licensed under the Apache License, ServerVersion 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:angle="90" android:startColor="#FFFFFFFF" android:endColor="#99FFFFFF" />
</shape>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 Jorge Ruesga
Licensed under the Apache License, ServerVersion 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.
-->
<resources>
<declare-styleable name="ExpandableViewLayout">
<attr name="maxHeight" format="dimension"/>
<attr name="expanded" format="boolean"/>
</declare-styleable>
</resources>