Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 1846765

Browse files
keianhzobluemarvin
authored andcommitted
Add hover animations to the languages and popup row icons (#2332)
1 parent 60a4bf1 commit 1846765

File tree

6 files changed

+214
-65
lines changed

6 files changed

+214
-65
lines changed

app/src/common/shared/org/mozilla/vrbrowser/ui/adapters/LanguagesAdapter.java

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.mozilla.vrbrowser.ui.adapters;
22

3+
import android.animation.ValueAnimator;
34
import android.annotation.SuppressLint;
5+
import android.content.Context;
46
import android.view.LayoutInflater;
57
import android.view.MotionEvent;
68
import android.view.View;
79
import android.view.ViewGroup;
810
import android.view.animation.AnimationUtils;
11+
import android.widget.ImageView;
912

1013
import androidx.annotation.NonNull;
1114
import androidx.annotation.Nullable;
@@ -23,16 +26,29 @@
2326

2427
public class LanguagesAdapter extends RecyclerView.Adapter<LanguagesAdapter.LanguageViewHolder> {
2528

29+
private static final int ICON_ANIMATION_DURATION = 200;
30+
2631
private List<Language> mLanguagesList;
2732
private boolean mIsPreferred;
2833

34+
private int mIconColorHover;
35+
private int mIconNormalColor;
36+
private int mIconSize;
37+
private int mMaxIconSize;
38+
2939
@Nullable
3040
private final LanguageItemCallback mLanguageItemCallback;
3141

32-
public LanguagesAdapter(@Nullable LanguageItemCallback clickCallback, boolean isPreferred) {
42+
public LanguagesAdapter(@NonNull Context context, @Nullable LanguageItemCallback clickCallback, boolean isPreferred) {
3343
mLanguageItemCallback = clickCallback;
3444
mIsPreferred = isPreferred;
3545

46+
mIconSize = (int)context.getResources().getDimension(R.dimen.language_row_icon_size);
47+
mMaxIconSize = mIconSize + ((mIconSize*25)/100);
48+
49+
mIconColorHover = context.getResources().getColor(R.color.smoke, context.getTheme());
50+
mIconNormalColor = context.getResources().getColor(R.color.concrete, context.getTheme());
51+
3652
setHasStableIds(true);
3753
}
3854

@@ -123,6 +139,10 @@ public LanguageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int view
123139
LanguageItemBinding binding = DataBindingUtil
124140
.inflate(LayoutInflater.from(parent.getContext()), R.layout.language_item,
125141
parent, false);
142+
binding.add.setOnHoverListener(mIconHoverListener);
143+
binding.delete.setOnHoverListener(mIconHoverListener);
144+
binding.up.setOnHoverListener(mIconHoverListener);
145+
binding.down.setOnHoverListener(mIconHoverListener);
126146
binding.setIsPreferred(mIsPreferred);
127147

128148
return new LanguageViewHolder(binding);
@@ -187,4 +207,44 @@ public long getItemId(int position) {
187207
return position;
188208
}
189209

210+
private View.OnHoverListener mIconHoverListener = (view, motionEvent) -> {
211+
ImageView icon = (ImageView)view;
212+
int ev = motionEvent.getActionMasked();
213+
switch (ev) {
214+
case MotionEvent.ACTION_HOVER_ENTER: {
215+
icon.setColorFilter(mIconColorHover);
216+
ValueAnimator anim = ValueAnimator.ofInt(mIconSize, mMaxIconSize);
217+
anim.addUpdateListener(valueAnimator -> {
218+
int val = (Integer) valueAnimator.getAnimatedValue();
219+
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
220+
layoutParams.width = val;
221+
layoutParams.height = val;
222+
view.setLayoutParams(layoutParams);
223+
});
224+
anim.setDuration(ICON_ANIMATION_DURATION);
225+
anim.start();
226+
227+
return false;
228+
}
229+
230+
case MotionEvent.ACTION_HOVER_EXIT: {
231+
ValueAnimator anim = ValueAnimator.ofInt(mMaxIconSize, mIconSize);
232+
anim.addUpdateListener(valueAnimator -> {
233+
int val = (Integer) valueAnimator.getAnimatedValue();
234+
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
235+
layoutParams.width = val;
236+
layoutParams.height = val;
237+
view.setLayoutParams(layoutParams);
238+
});
239+
anim.setDuration(ICON_ANIMATION_DURATION);
240+
anim.start();
241+
icon.setColorFilter(mIconNormalColor);
242+
243+
return false;
244+
}
245+
}
246+
247+
return false;
248+
};
249+
190250
}

app/src/common/shared/org/mozilla/vrbrowser/ui/adapters/PopUpAdapter.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package org.mozilla.vrbrowser.ui.adapters;
22

3+
import android.animation.ValueAnimator;
34
import android.content.Context;
45
import android.view.LayoutInflater;
56
import android.view.MotionEvent;
7+
import android.view.View;
68
import android.view.ViewGroup;
9+
import android.widget.ImageView;
710

811
import androidx.annotation.NonNull;
912
import androidx.databinding.DataBindingUtil;
@@ -24,13 +27,26 @@ public class PopUpAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
2427

2528
static final String LOGTAG = SystemUtils.createLogtag(BookmarkAdapter.class);
2629

30+
private static final int ICON_ANIMATION_DURATION = 200;
31+
2732
private List<PopUpSite> mDisplayList;
2833

2934
private PopUpSiteItemCallback mCallback;
3035

36+
private int mIconColorHover;
37+
private int mIconNormalColor;
38+
private int mIconSize;
39+
private int mMaxIconSize;
40+
3141
public PopUpAdapter(Context aContext, PopUpSiteItemCallback callback) {
3242
mCallback = callback;
3343

44+
mIconSize = (int)aContext.getResources().getDimension(R.dimen.language_row_icon_size);
45+
mMaxIconSize = mIconSize + ((mIconSize*25)/100);
46+
47+
mIconColorHover = aContext.getResources().getColor(R.color.smoke, aContext.getTheme());
48+
mIconNormalColor = aContext.getResources().getColor(R.color.concrete, aContext.getTheme());
49+
3450
setHasStableIds(true);
3551
}
3652

@@ -93,6 +109,7 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int
93109

94110
return false;
95111
});
112+
binding.delete.setOnHoverListener(mIconHoverListener);
96113

97114
return new PopUpSiteViewHolder(binding);
98115
}
@@ -119,5 +136,45 @@ static class PopUpSiteViewHolder extends RecyclerView.ViewHolder {
119136
}
120137
}
121138

139+
private View.OnHoverListener mIconHoverListener = (view, motionEvent) -> {
140+
ImageView icon = (ImageView)view;
141+
int ev = motionEvent.getActionMasked();
142+
switch (ev) {
143+
case MotionEvent.ACTION_HOVER_ENTER: {
144+
icon.setColorFilter(mIconColorHover);
145+
ValueAnimator anim = ValueAnimator.ofInt(mIconSize, mMaxIconSize);
146+
anim.addUpdateListener(valueAnimator -> {
147+
int val = (Integer) valueAnimator.getAnimatedValue();
148+
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
149+
layoutParams.width = val;
150+
layoutParams.height = val;
151+
view.setLayoutParams(layoutParams);
152+
});
153+
anim.setDuration(ICON_ANIMATION_DURATION);
154+
anim.start();
155+
156+
return false;
157+
}
158+
159+
case MotionEvent.ACTION_HOVER_EXIT: {
160+
ValueAnimator anim = ValueAnimator.ofInt(mMaxIconSize, mIconSize);
161+
anim.addUpdateListener(valueAnimator -> {
162+
int val = (Integer) valueAnimator.getAnimatedValue();
163+
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
164+
layoutParams.width = val;
165+
layoutParams.height = val;
166+
view.setLayoutParams(layoutParams);
167+
});
168+
anim.setDuration(ICON_ANIMATION_DURATION);
169+
anim.start();
170+
icon.setColorFilter(mIconNormalColor);
171+
172+
return false;
173+
}
174+
}
175+
176+
return false;
177+
};
178+
122179
}
123180

app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/settings/ContentLanguageOptionsView.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ private void initialize(Context aContext) {
4141
LayoutInflater inflater = LayoutInflater.from(aContext);
4242

4343
// Preferred languages adapter
44-
mPreferredAdapter = new LanguagesAdapter(mLanguageItemCallback, true);
44+
mPreferredAdapter = new LanguagesAdapter(getContext(), mLanguageItemCallback, true);
4545
mPreferredAdapter.setLanguageList(LocaleUtils.getPreferredLanguages(getContext()));
4646

4747
// Available languages adapter
48-
mAvailableAdapter = new LanguagesAdapter(mLanguageItemCallback, false);
48+
mAvailableAdapter = new LanguagesAdapter(getContext(), mLanguageItemCallback, false);
4949
mAvailableAdapter.setLanguageList(LocaleUtils.getAvailableLanguages());
5050

5151
// Inflate this data binding layout

app/src/main/res/drawable/ic_icon_language_delete.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<selector xmlns:android="http://schemas.android.com/apk/res/android"
33
android:enterFadeDuration="@integer/ui_fadeAnimTime"
44
android:exitFadeDuration="@integer/ui_fadeAnimTime">
5-
<item android:drawable="@drawable/ic_icon_delete" android:state_hovered="true" />
6-
<item android:drawable="@drawable/ic_icon_delete" android:state_pressed="true" />
5+
<item android:drawable="@drawable/ic_icon_delete" android:state_hovered="true" android:color="@color/smoke" />
6+
<item android:drawable="@drawable/ic_icon_delete" android:state_pressed="true" android:color="@color/void_color" />
77
<item android:drawable="@android:color/transparent" />
88
</selector>

app/src/main/res/layout/language_item.xml

Lines changed: 76 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -43,34 +43,54 @@
4343
android:duplicateParentState="true"
4444
android:orientation="horizontal">
4545

46-
<ImageView
47-
android:id="@+id/add"
46+
<FrameLayout
4847
android:layout_width="@dimen/language_row_icon_size"
4948
android:layout_height="@dimen/language_row_icon_size"
50-
android:layout_gravity="center"
51-
android:clickable="false"
52-
android:contentDescription="TODO"
53-
android:duplicateParentState="true"
54-
android:soundEffectsEnabled="false"
55-
android:src="@{language.isPreferred ? @drawable/ic_icon_check : @drawable/ic_icon_language_add}"
56-
android:tint="@color/fog"
57-
app:srcCompat="@drawable/ic_icon_language_add"
58-
app:visibleGone="@{!isPreferred}" />
59-
60-
<ImageView
61-
android:id="@+id/delete"
62-
android:layout_width="@dimen/language_row_icon_size"
63-
android:layout_height="@dimen/language_row_icon_size"
64-
android:layout_centerVertical="true"
65-
android:layout_gravity="center"
66-
android:clickable="false"
67-
android:contentDescription="Preferred language delete button"
68-
android:duplicateParentState="true"
69-
android:soundEffectsEnabled="false"
70-
android:src="@{@drawable/ic_icon_language_delete}"
71-
android:tint="@color/fog"
72-
app:srcCompat="@drawable/ic_icon_language_delete"
73-
app:visibleGone="@{isPreferred}" />
49+
android:duplicateParentState="true">
50+
51+
<ImageView
52+
android:id="@+id/add"
53+
android:layout_width="match_parent"
54+
android:layout_height="match_parent"
55+
android:layout_gravity="center"
56+
android:clickable="false"
57+
android:contentDescription="TODO"
58+
android:duplicateParentState="true"
59+
android:soundEffectsEnabled="false"
60+
android:src="@drawable/ic_icon_language_add"
61+
android:tint="@color/fog"
62+
app:srcCompat="@drawable/ic_icon_language_add"
63+
app:visibleGone="@{!isPreferred &amp;&amp; !language.isPreferred}" />
64+
65+
<ImageView
66+
android:id="@+id/added"
67+
android:layout_width="match_parent"
68+
android:layout_height="match_parent"
69+
android:layout_gravity="center"
70+
android:clickable="false"
71+
android:contentDescription="TODO"
72+
android:duplicateParentState="true"
73+
android:soundEffectsEnabled="false"
74+
android:src="@drawable/ic_icon_check"
75+
android:tint="@color/fog"
76+
app:srcCompat="@drawable/ic_icon_check"
77+
app:visibleGone="@{!isPreferred &amp;&amp; language.isPreferred}" />
78+
79+
<ImageView
80+
android:id="@+id/delete"
81+
android:layout_width="match_parent"
82+
android:layout_height="match_parent"
83+
android:layout_gravity="center"
84+
android:clickable="false"
85+
android:contentDescription="Preferred language delete button"
86+
android:duplicateParentState="true"
87+
android:soundEffectsEnabled="false"
88+
android:src="@{@drawable/ic_icon_language_delete}"
89+
android:tint="@color/fog"
90+
app:srcCompat="@drawable/ic_icon_language_delete"
91+
app:visibleGone="@{isPreferred}" />
92+
93+
</FrameLayout>
7494

7595
</LinearLayout>
7696

@@ -109,31 +129,38 @@
109129
android:duplicateParentState="true"
110130
android:orientation="horizontal">
111131

112-
<ImageView
113-
android:id="@+id/up"
132+
<FrameLayout
114133
android:layout_width="@dimen/language_row_icon_size"
115134
android:layout_height="@dimen/language_row_icon_size"
116-
android:layout_gravity="center"
117-
android:contentDescription="TODO"
118-
android:duplicateParentState="true"
119-
android:soundEffectsEnabled="false"
120-
android:src="@drawable/ic_icon_language_move_up"
121-
android:tint="@color/fog"
122-
app:srcCompat="@drawable/ic_icon_language_move_up"
123-
app:visibleGone="@{isPreferred &amp;&amp; !isFirst}" />
124-
125-
<ImageView
126-
android:id="@+id/down"
127-
android:layout_width="@dimen/language_row_icon_size"
128-
android:layout_height="@dimen/language_row_icon_size"
129-
android:layout_gravity="center"
130-
android:contentDescription="TODO"
131-
android:duplicateParentState="true"
132-
android:soundEffectsEnabled="false"
133-
android:src="@drawable/ic_icon_language_move_down"
134-
android:tint="@color/fog"
135-
app:srcCompat="@drawable/ic_icon_language_move_down"
136-
app:visibleGone="@{isPreferred &amp;&amp; !isLast}" />
135+
android:duplicateParentState="true">
136+
137+
<ImageView
138+
android:id="@+id/up"
139+
android:layout_width="match_parent"
140+
android:layout_height="match_parent"
141+
android:layout_gravity="center"
142+
android:contentDescription="TODO"
143+
android:duplicateParentState="true"
144+
android:soundEffectsEnabled="false"
145+
android:src="@drawable/ic_icon_language_move_up"
146+
android:tint="@color/fog"
147+
app:srcCompat="@drawable/ic_icon_language_move_up"
148+
app:visibleGone="@{isPreferred &amp;&amp; !isFirst}" />
149+
150+
<ImageView
151+
android:id="@+id/down"
152+
android:layout_width="match_parent"
153+
android:layout_height="match_parent"
154+
android:layout_gravity="center"
155+
android:contentDescription="TODO"
156+
android:duplicateParentState="true"
157+
android:soundEffectsEnabled="false"
158+
android:src="@drawable/ic_icon_language_move_down"
159+
android:tint="@color/fog"
160+
app:srcCompat="@drawable/ic_icon_language_move_down"
161+
app:visibleGone="@{isPreferred &amp;&amp; !isLast}" />
162+
163+
</FrameLayout>
137164
</LinearLayout>
138165
</RelativeLayout>
139166
</layout>

0 commit comments

Comments
 (0)