kopia lustrzana https://github.com/ryukoposting/Signal-Android
Inset audio level indicator by nav bar height.
rodzic
530403ec04
commit
33d28c4359
|
@ -13,7 +13,9 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.widget.AppCompatImageView;
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.view.ViewKt;
|
||||||
import androidx.core.widget.ImageViewCompat;
|
import androidx.core.widget.ImageViewCompat;
|
||||||
|
import androidx.transition.TransitionManager;
|
||||||
|
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
|
||||||
|
@ -226,6 +228,17 @@ public class CallParticipantView extends ConstraintLayout {
|
||||||
changeAvatarParams(SMALL_AVATAR);
|
changeAvatarParams(SMALL_AVATAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBottomInset(int bottomInset) {
|
||||||
|
int desiredMargin = getResources().getDimensionPixelSize(R.dimen.webrtc_audio_indicator_margin) + bottomInset;
|
||||||
|
if (ViewKt.getMarginBottom(audioIndicator) == desiredMargin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransitionManager.beginDelayedTransition(this);
|
||||||
|
|
||||||
|
ViewUtil.setBottomMargin(audioIndicator, desiredMargin);
|
||||||
|
}
|
||||||
|
|
||||||
void releaseRenderer() {
|
void releaseRenderer() {
|
||||||
renderer.release();
|
renderer.release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
|
||||||
private boolean shouldRenderInPip;
|
private boolean shouldRenderInPip;
|
||||||
private boolean isPortrait;
|
private boolean isPortrait;
|
||||||
private boolean isIncomingRing;
|
private boolean isIncomingRing;
|
||||||
|
private int navBarBottomInset;
|
||||||
private LayoutStrategy layoutStrategy;
|
private LayoutStrategy layoutStrategy;
|
||||||
|
|
||||||
public CallParticipantsLayout(@NonNull Context context) {
|
public CallParticipantsLayout(@NonNull Context context) {
|
||||||
|
@ -53,6 +54,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
|
||||||
boolean shouldRenderInPip,
|
boolean shouldRenderInPip,
|
||||||
boolean isPortrait,
|
boolean isPortrait,
|
||||||
boolean isIncomingRing,
|
boolean isIncomingRing,
|
||||||
|
int navBarBottomInset,
|
||||||
@NonNull LayoutStrategy layoutStrategy)
|
@NonNull LayoutStrategy layoutStrategy)
|
||||||
{
|
{
|
||||||
this.callParticipants = callParticipants;
|
this.callParticipants = callParticipants;
|
||||||
|
@ -60,6 +62,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
|
||||||
this.shouldRenderInPip = shouldRenderInPip;
|
this.shouldRenderInPip = shouldRenderInPip;
|
||||||
this.isPortrait = isPortrait;
|
this.isPortrait = isPortrait;
|
||||||
this.isIncomingRing = isIncomingRing;
|
this.isIncomingRing = isIncomingRing;
|
||||||
|
this.navBarBottomInset = navBarBottomInset;
|
||||||
this.layoutStrategy = layoutStrategy;
|
this.layoutStrategy = layoutStrategy;
|
||||||
|
|
||||||
setFlexDirection(layoutStrategy.getFlexDirection());
|
setFlexDirection(layoutStrategy.getFlexDirection());
|
||||||
|
@ -123,9 +126,11 @@ public class CallParticipantsLayout extends FlexboxLayout {
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
view.setPadding(MULTIPLE_PARTICIPANT_SPACING, MULTIPLE_PARTICIPANT_SPACING, MULTIPLE_PARTICIPANT_SPACING, MULTIPLE_PARTICIPANT_SPACING);
|
view.setPadding(MULTIPLE_PARTICIPANT_SPACING, MULTIPLE_PARTICIPANT_SPACING, MULTIPLE_PARTICIPANT_SPACING, MULTIPLE_PARTICIPANT_SPACING);
|
||||||
cardView.setRadius(CORNER_RADIUS);
|
cardView.setRadius(CORNER_RADIUS);
|
||||||
|
callParticipantView.setBottomInset(0);
|
||||||
} else {
|
} else {
|
||||||
view.setPadding(0, 0, 0, 0);
|
view.setPadding(0, 0, 0, 0);
|
||||||
cardView.setRadius(0);
|
cardView.setRadius(0);
|
||||||
|
callParticipantView.setBottomInset(navBarBottomInset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isIncomingRing) {
|
if (isIncomingRing) {
|
||||||
|
|
|
@ -17,15 +17,17 @@ class WebRtcCallParticipantsPage {
|
||||||
private final boolean isPortrait;
|
private final boolean isPortrait;
|
||||||
private final boolean isLandscapeEnabled;
|
private final boolean isLandscapeEnabled;
|
||||||
private final boolean isIncomingRing;
|
private final boolean isIncomingRing;
|
||||||
|
private final int navBarBottomInset;
|
||||||
|
|
||||||
static WebRtcCallParticipantsPage forMultipleParticipants(@NonNull List<CallParticipant> callParticipants,
|
static WebRtcCallParticipantsPage forMultipleParticipants(@NonNull List<CallParticipant> callParticipants,
|
||||||
@NonNull CallParticipant focusedParticipant,
|
@NonNull CallParticipant focusedParticipant,
|
||||||
boolean isRenderInPip,
|
boolean isRenderInPip,
|
||||||
boolean isPortrait,
|
boolean isPortrait,
|
||||||
boolean isLandscapeEnabled,
|
boolean isLandscapeEnabled,
|
||||||
boolean isIncomingRing)
|
boolean isIncomingRing,
|
||||||
|
int navBarBottomInset)
|
||||||
{
|
{
|
||||||
return new WebRtcCallParticipantsPage(callParticipants, focusedParticipant, false, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing);
|
return new WebRtcCallParticipantsPage(callParticipants, focusedParticipant, false, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing, navBarBottomInset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebRtcCallParticipantsPage forSingleParticipant(@NonNull CallParticipant singleParticipant,
|
static WebRtcCallParticipantsPage forSingleParticipant(@NonNull CallParticipant singleParticipant,
|
||||||
|
@ -33,7 +35,7 @@ class WebRtcCallParticipantsPage {
|
||||||
boolean isPortrait,
|
boolean isPortrait,
|
||||||
boolean isLandscapeEnabled)
|
boolean isLandscapeEnabled)
|
||||||
{
|
{
|
||||||
return new WebRtcCallParticipantsPage(Collections.singletonList(singleParticipant), singleParticipant, true, isRenderInPip, isPortrait, isLandscapeEnabled, false);
|
return new WebRtcCallParticipantsPage(Collections.singletonList(singleParticipant), singleParticipant, true, isRenderInPip, isPortrait, isLandscapeEnabled, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebRtcCallParticipantsPage(@NonNull List<CallParticipant> callParticipants,
|
private WebRtcCallParticipantsPage(@NonNull List<CallParticipant> callParticipants,
|
||||||
|
@ -42,7 +44,8 @@ class WebRtcCallParticipantsPage {
|
||||||
boolean isRenderInPip,
|
boolean isRenderInPip,
|
||||||
boolean isPortrait,
|
boolean isPortrait,
|
||||||
boolean isLandscapeEnabled,
|
boolean isLandscapeEnabled,
|
||||||
boolean isIncomingRing)
|
boolean isIncomingRing,
|
||||||
|
int navBarBottomInset)
|
||||||
{
|
{
|
||||||
this.callParticipants = callParticipants;
|
this.callParticipants = callParticipants;
|
||||||
this.focusedParticipant = focusedParticipant;
|
this.focusedParticipant = focusedParticipant;
|
||||||
|
@ -51,6 +54,7 @@ class WebRtcCallParticipantsPage {
|
||||||
this.isPortrait = isPortrait;
|
this.isPortrait = isPortrait;
|
||||||
this.isLandscapeEnabled = isLandscapeEnabled;
|
this.isLandscapeEnabled = isLandscapeEnabled;
|
||||||
this.isIncomingRing = isIncomingRing;
|
this.isIncomingRing = isIncomingRing;
|
||||||
|
this.navBarBottomInset = navBarBottomInset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull List<CallParticipant> getCallParticipants() {
|
public @NonNull List<CallParticipant> getCallParticipants() {
|
||||||
|
@ -77,6 +81,10 @@ class WebRtcCallParticipantsPage {
|
||||||
return isIncomingRing;
|
return isIncomingRing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNavBarBottomInset() {
|
||||||
|
return navBarBottomInset;
|
||||||
|
}
|
||||||
|
|
||||||
public @NonNull CallParticipantsLayout.LayoutStrategy getLayoutStrategy() {
|
public @NonNull CallParticipantsLayout.LayoutStrategy getLayoutStrategy() {
|
||||||
return CallParticipantsLayoutStrategies.getStrategy(isPortrait, isLandscapeEnabled);
|
return CallParticipantsLayoutStrategies.getStrategy(isPortrait, isLandscapeEnabled);
|
||||||
}
|
}
|
||||||
|
@ -92,11 +100,12 @@ class WebRtcCallParticipantsPage {
|
||||||
isLandscapeEnabled == that.isLandscapeEnabled &&
|
isLandscapeEnabled == that.isLandscapeEnabled &&
|
||||||
isIncomingRing == that.isIncomingRing &&
|
isIncomingRing == that.isIncomingRing &&
|
||||||
callParticipants.equals(that.callParticipants) &&
|
callParticipants.equals(that.callParticipants) &&
|
||||||
focusedParticipant.equals(that.focusedParticipant);
|
focusedParticipant.equals(that.focusedParticipant) &&
|
||||||
|
navBarBottomInset == that.navBarBottomInset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(callParticipants, focusedParticipant, isSpeaker, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing);
|
return Objects.hash(callParticipants, focusedParticipant, isSpeaker, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing, navBarBottomInset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ class WebRtcCallParticipantsPagerAdapter extends ListAdapter<WebRtcCallParticipa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void bind(WebRtcCallParticipantsPage page) {
|
void bind(WebRtcCallParticipantsPage page) {
|
||||||
callParticipantsLayout.update(page.getCallParticipants(), page.getFocusedParticipant(), page.isRenderInPip(), page.isPortrait(), page.isIncomingRing(), page.getLayoutStrategy());
|
callParticipantsLayout.update(page.getCallParticipants(), page.getFocusedParticipant(), page.isRenderInPip(), page.isPortrait(), page.isIncomingRing(), page.getNavBarBottomInset(), page.getLayoutStrategy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.graphics.Rect;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowInsets;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
@ -21,6 +22,7 @@ import androidx.constraintlayout.widget.ConstraintSet;
|
||||||
import androidx.constraintlayout.widget.Guideline;
|
import androidx.constraintlayout.widget.Guideline;
|
||||||
import androidx.core.util.Consumer;
|
import androidx.core.util.Consumer;
|
||||||
import androidx.core.view.ViewKt;
|
import androidx.core.view.ViewKt;
|
||||||
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.transition.AutoTransition;
|
import androidx.transition.AutoTransition;
|
||||||
|
@ -122,6 +124,7 @@ public class WebRtcCallView extends ConstraintLayout {
|
||||||
private ConstraintSet largeHeaderConstraints;
|
private ConstraintSet largeHeaderConstraints;
|
||||||
private ConstraintSet smallHeaderConstraints;
|
private ConstraintSet smallHeaderConstraints;
|
||||||
private Guideline statusBarGuideline;
|
private Guideline statusBarGuideline;
|
||||||
|
private int navBarBottomInset;
|
||||||
private View fullScreenShade;
|
private View fullScreenShade;
|
||||||
|
|
||||||
private WebRtcCallParticipantsPagerAdapter pagerAdapter;
|
private WebRtcCallParticipantsPagerAdapter pagerAdapter;
|
||||||
|
@ -142,6 +145,8 @@ public class WebRtcCallView extends ConstraintLayout {
|
||||||
if (isAttachedToWindow() && controls.isFadeOutEnabled()) fadeOutControls();
|
if (isAttachedToWindow() && controls.isFadeOutEnabled()) fadeOutControls();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private CallParticipantsViewState lastState;
|
||||||
|
|
||||||
public WebRtcCallView(@NonNull Context context) {
|
public WebRtcCallView(@NonNull Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
|
@ -333,6 +338,19 @@ public class WebRtcCallView extends ConstraintLayout {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= 20) {
|
||||||
|
navBarBottomInset = WindowInsetsCompat.toWindowInsetsCompat(insets).getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
||||||
|
|
||||||
|
if (lastState != null) {
|
||||||
|
updateCallParticipants(lastState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onApplyWindowInsets(insets);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWindowSystemUiVisibilityChanged(int visible) {
|
public void onWindowSystemUiVisibilityChanged(int visible) {
|
||||||
if ((visible & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
|
if ((visible & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
|
||||||
|
@ -371,13 +389,15 @@ public class WebRtcCallView extends ConstraintLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCallParticipants(@NonNull CallParticipantsViewState callParticipantsViewState) {
|
public void updateCallParticipants(@NonNull CallParticipantsViewState callParticipantsViewState) {
|
||||||
|
lastState = callParticipantsViewState;
|
||||||
|
|
||||||
CallParticipantsState state = callParticipantsViewState.getCallParticipantsState();
|
CallParticipantsState state = callParticipantsViewState.getCallParticipantsState();
|
||||||
boolean isPortrait = callParticipantsViewState.isPortrait();
|
boolean isPortrait = callParticipantsViewState.isPortrait();
|
||||||
boolean isLandscapeEnabled = callParticipantsViewState.isLandscapeEnabled();
|
boolean isLandscapeEnabled = callParticipantsViewState.isLandscapeEnabled();
|
||||||
List<WebRtcCallParticipantsPage> pages = new ArrayList<>(2);
|
List<WebRtcCallParticipantsPage> pages = new ArrayList<>(2);
|
||||||
|
|
||||||
if (!state.getGridParticipants().isEmpty()) {
|
if (!state.getGridParticipants().isEmpty()) {
|
||||||
pages.add(WebRtcCallParticipantsPage.forMultipleParticipants(state.getGridParticipants(), state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled, state.isIncomingRing()));
|
pages.add(WebRtcCallParticipantsPage.forMultipleParticipants(state.getGridParticipants(), state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled, state.isIncomingRing(), navBarBottomInset));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.getFocusedParticipant() != CallParticipant.EMPTY && state.getAllRemoteParticipants().size() > 1) {
|
if (state.getFocusedParticipant() != CallParticipant.EMPTY && state.getAllRemoteParticipants().size() > 1) {
|
||||||
|
|
|
@ -87,8 +87,8 @@
|
||||||
android:id="@+id/call_participant_audio_indicator"
|
android:id="@+id/call_participant_audio_indicator"
|
||||||
android:layout_width="20dp"
|
android:layout_width="20dp"
|
||||||
android:layout_height="20dp"
|
android:layout_height="20dp"
|
||||||
android:layout_marginStart="14dp"
|
android:layout_marginStart="@dimen/webrtc_audio_indicator_margin"
|
||||||
android:layout_marginBottom="14dp"
|
android:layout_marginBottom="@dimen/webrtc_audio_indicator_margin"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,9 @@
|
||||||
<dimen name="verify_identity_vertical_margin">16dp</dimen>
|
<dimen name="verify_identity_vertical_margin">16dp</dimen>
|
||||||
|
|
||||||
<dimen name="signal_context_menu_corner_radius">18dp</dimen>
|
<dimen name="signal_context_menu_corner_radius">18dp</dimen>
|
||||||
|
|
||||||
<dimen name="webrtc_button_size">48dp</dimen>
|
<dimen name="webrtc_button_size">48dp</dimen>
|
||||||
|
<dimen name="webrtc_audio_indicator_margin">14dp</dimen>
|
||||||
|
|
||||||
<dimen name="segmentedprogressbar_default_segment_margin">8dp</dimen>
|
<dimen name="segmentedprogressbar_default_segment_margin">8dp</dimen>
|
||||||
<dimen name="segmentedprogressbar_default_corner_radius">0dp</dimen>
|
<dimen name="segmentedprogressbar_default_corner_radius">0dp</dimen>
|
||||||
|
|
Ładowanie…
Reference in New Issue