Skip to content

Commit 7744ce4

Browse files
dipjadipjadipja
authored
Feature - [Android] Dynamic Type Ahead (#8272)
* adding choices resolver for base element renderer * moving card level host interactions using channel adaptor * resolving comments * Adding resources for dynamic type ahead UI and new screen for type ahead (#8273) * adding resources for dynamic type ahead ui * adding custom icons * fix typo * addressing comments * adding msft copyright * Adding new screen for dynamic type ahead (#8274) * adding new screen for dynamic type ahead * removing comments * updating sample app to use channel adaptor to fetch dynamic choices * fixing customization support in new type ahead screen * setting content description for buttons --------- Co-authored-by: dipja <dipja@Dipeshs-MacBook-Pro.local> Co-authored-by: dipja <dipja@Dipeshs-MBP.guest.corp.microsoft.com> --------- Co-authored-by: dipja <dipja@Dipeshs-MacBook-Pro.local> Co-authored-by: dipja <dipja@Dipeshs-MBP.guest.corp.microsoft.com> * highting query text in dynamic choices * fixing error message visibility --------- Co-authored-by: dipja <dipja@Dipeshs-MacBook-Pro.local> Co-authored-by: dipja <dipja@Dipeshs-MBP.guest.corp.microsoft.com>
1 parent 71a0ff8 commit 7744ce4

File tree

76 files changed

+1820
-142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1820
-142
lines changed

source/android/adaptivecards/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ android {
2626
}
2727
}
2828
}
29+
buildFeatures {
30+
dataBinding true
31+
}
2932
buildTypes {
3033
release {
3134
minifyEnabled false
@@ -186,4 +189,9 @@ dependencies {
186189
implementation 'androidx.core:core-ktx:' + androidxKotlinCoreVersion
187190
implementation 'com.google.android.exoplayer:exoplayer:' + androidExoPlayerVersion
188191
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
192+
implementation 'androidx.recyclerview:recyclerview:' + androidxRecyclerViewVersion
193+
implementation 'androidx.recyclerview:recyclerview-selection:' + androidxRecyclerViewSelectionVersion
194+
implementation 'com.google.android.material:material:' + androidMaterialVersion
195+
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:' + androidxLifecycleVersion
196+
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:' + androidxLifecycleVersion
189197
}

source/android/adaptivecards/src/androidTest/java/io/adaptivecards/objectmodel/APITest.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.adaptivecards.renderer.AdaptiveFallbackException;
2020
import io.adaptivecards.renderer.BaseActionElementRenderer;
2121
import io.adaptivecards.renderer.BaseCardElementRenderer;
22+
import io.adaptivecards.renderer.ChannelAdaptor;
2223
import io.adaptivecards.renderer.RenderArgs;
2324
import io.adaptivecards.renderer.RenderedAdaptiveCard;
2425
import io.adaptivecards.renderer.Util;
@@ -89,11 +90,11 @@ public CustomActionListener(RenderedAdaptiveCard renderedCard,
8990
FragmentManager fragmentManager,
9091
ViewGroup viewGroup,
9192
BaseActionElement baseActionElement,
92-
ICardActionHandler cardActionHandler,
93+
ChannelAdaptor channelAdaptor,
9394
HostConfig hostConfig,
9495
RenderArgs renderArgs)
9596
{
96-
super(renderedCard, context, fragmentManager, viewGroup, baseActionElement, cardActionHandler, hostConfig, renderArgs);
97+
super(renderedCard, context, fragmentManager, viewGroup, baseActionElement, channelAdaptor, hostConfig, renderArgs);
9798
}
9899

99100
public CustomActionListener(RenderedAdaptiveCard renderedCard,
@@ -150,7 +151,7 @@ public Button render(RenderedAdaptiveCard renderedCard,
150151
FragmentManager fragmentManager,
151152
ViewGroup viewGroup,
152153
BaseActionElement baseActionElement,
153-
ICardActionHandler cardActionHandler,
154+
ChannelAdaptor channelAdaptor,
154155
HostConfig hostConfig,
155156
RenderArgs renderArgs) throws AdaptiveFallbackException
156157
{
@@ -159,11 +160,11 @@ public Button render(RenderedAdaptiveCard renderedCard,
159160
fragmentManager,
160161
viewGroup,
161162
baseActionElement,
162-
cardActionHandler,
163+
channelAdaptor,
163164
hostConfig,
164165
renderArgs);
165166

166-
blueAction.setOnClickListener(new CustomActionListener(renderedCard, baseActionElement, cardActionHandler));
167+
blueAction.setOnClickListener(new CustomActionListener(renderedCard, baseActionElement, channelAdaptor.getCardActionHandler()));
167168
renderedCard.registerSubmitableAction(blueAction, renderArgs);
168169

169170
renderedButton = blueAction;
@@ -240,7 +241,7 @@ public static class MockImageRendererExpectingAncestorWithNoSelectActionRenderer
240241

241242
@Override
242243
public View render(RenderedAdaptiveCard renderedCard, Context context, FragmentManager fragmentManager,
243-
ViewGroup viewGroup, BaseCardElement baseCardElement, ICardActionHandler cardActionHandler,
244+
ViewGroup viewGroup, BaseCardElement baseCardElement, ChannelAdaptor channelAdaptor,
244245
HostConfig hostConfig, RenderArgs renderArgs) throws Exception
245246
{
246247
ImageView img = new ImageView(context);
@@ -260,7 +261,7 @@ public static class MockImageRendererExpectingAncestorWithSelectActionRenderer e
260261

261262
@Override
262263
public View render(RenderedAdaptiveCard renderedCard, Context context, FragmentManager fragmentManager,
263-
ViewGroup viewGroup, BaseCardElement baseCardElement, ICardActionHandler cardActionHandler,
264+
ViewGroup viewGroup, BaseCardElement baseCardElement, ChannelAdaptor channelAdaptor,
264265
HostConfig hostConfig, RenderArgs renderArgs) throws Exception
265266
{
266267
ImageView img = new ImageView(context);

source/android/adaptivecards/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
<application android:allowBackup="true" android:label="@string/app_name"
66
android:supportsRtl="true">
7-
7+
<activity
8+
android:name=".renderer.typeaheadsearch.TypeAheadSearchActivity" />
89
</application>
910

1011
</manifest>

source/android/adaptivecards/src/main/java/io/adaptivecards/renderer/ActionLayoutRenderer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import io.adaptivecards.objectmodel.FeatureRegistration;
2121
import io.adaptivecards.objectmodel.HostConfig;
2222
import io.adaptivecards.objectmodel.Spacing;
23-
import io.adaptivecards.renderer.actionhandler.ICardActionHandler;
2423
import io.adaptivecards.renderer.registration.CardRendererRegistration;
2524

2625
public class ActionLayoutRenderer implements IActionLayoutRenderer {
@@ -45,7 +44,7 @@ public View renderActions(
4544
FragmentManager fragmentManager,
4645
ViewGroup viewGroup,
4746
BaseActionElementVector baseActionElementList,
48-
ICardActionHandler cardActionHandler,
47+
ChannelAdaptor channelAdaptor,
4948
HostConfig hostConfig,
5049
RenderArgs renderArgs) throws AdaptiveFallbackException
5150
{
@@ -138,7 +137,7 @@ else if (alignment == ActionAlignment.Center.swigValue())
138137
throw new AdaptiveFallbackException(actionElement, featureRegistration);
139138
}
140139

141-
actionRenderer.render(renderedCard, context, fragmentManager, actionButtonsLayout, actionElement, cardActionHandler, hostConfig, renderArgs);
140+
actionRenderer.render(renderedCard, context, fragmentManager, actionButtonsLayout, actionElement, channelAdaptor, hostConfig, renderArgs);
142141
}
143142
catch (AdaptiveFallbackException e)
144143
{
@@ -167,7 +166,7 @@ else if (alignment == ActionAlignment.Center.swigValue())
167166
throw new AdaptiveFallbackException(fallbackElement, featureRegistration);
168167
}
169168

170-
fallbackActionRenderer.render(renderedCard, context, fragmentManager, actionButtonsLayout, fallbackActionElement, cardActionHandler, hostConfig, renderArgs);
169+
fallbackActionRenderer.render(renderedCard, context, fragmentManager, actionButtonsLayout, fallbackActionElement, channelAdaptor, hostConfig, renderArgs);
171170
break;
172171
}
173172
catch (AdaptiveFallbackException e2)

source/android/adaptivecards/src/main/java/io/adaptivecards/renderer/AdaptiveCardRenderer.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import android.content.Context;
66
import android.graphics.Color;
77

8+
import androidx.activity.result.ActivityResultRegistry;
9+
import androidx.annotation.NonNull;
810
import androidx.annotation.Nullable;
911
import androidx.fragment.app.FragmentManager;
1012
import android.util.Pair;
@@ -67,10 +69,35 @@ public RenderedAdaptiveCard render(
6769
ICardActionHandler cardActionHandler,
6870
@Nullable IOverflowActionRenderer overflowActionRenderer,
6971
HostConfig hostConfig)
72+
{
73+
ChannelAdaptor channelAdaptor = new ChannelAdaptor.Builder().actionHandler(cardActionHandler).build();
74+
return render(context, fragmentManager, adaptiveCard, channelAdaptor, overflowActionRenderer, null, hostConfig);
75+
}
76+
77+
public RenderedAdaptiveCard render(
78+
Context context,
79+
FragmentManager fragmentManager,
80+
AdaptiveCard adaptiveCard,
81+
ChannelAdaptor channelAdaptor,
82+
@Nullable ActivityResultRegistry activityResultRegistry,
83+
HostConfig hostConfig)
84+
{
85+
return render(context, fragmentManager, adaptiveCard, channelAdaptor, null, activityResultRegistry, hostConfig);
86+
}
87+
88+
public RenderedAdaptiveCard render(
89+
Context context,
90+
FragmentManager fragmentManager,
91+
AdaptiveCard adaptiveCard,
92+
@NonNull ChannelAdaptor channelAdaptor,
93+
@Nullable IOverflowActionRenderer overflowActionRenderer,
94+
@Nullable ActivityResultRegistry activityResultRegistry,
95+
HostConfig hostConfig)
7096
{
7197
RenderedAdaptiveCard result = new RenderedAdaptiveCard(adaptiveCard);
7298
CardRendererRegistration.getInstance().registerOverflowActionRenderer(overflowActionRenderer);
73-
View cardView = internalRender(result, context, fragmentManager, adaptiveCard, cardActionHandler, hostConfig, false, View.NO_ID);
99+
CardRendererRegistration.getInstance().registerActivityResultRegistry(activityResultRegistry);
100+
View cardView = internalRender(result, context, fragmentManager, adaptiveCard, channelAdaptor, hostConfig, false, View.NO_ID);
74101
result.setView(cardView);
75102
return result;
76103
}
@@ -79,14 +106,14 @@ private void renderCardElements(RenderedAdaptiveCard renderedCard,
79106
Context context,
80107
FragmentManager fragmentManager,
81108
AdaptiveCard adaptiveCard,
82-
ICardActionHandler cardActionHandler,
109+
ChannelAdaptor channelAdaptor,
83110
HostConfig hostConfig,
84111
ViewGroup cardLayout,
85112
RenderArgs renderArgs)
86113
{
87114
try
88115
{
89-
CardRendererRegistration.getInstance().renderElements(renderedCard, context, fragmentManager, cardLayout, adaptiveCard.GetBody(), cardActionHandler, hostConfig, renderArgs);
116+
CardRendererRegistration.getInstance().renderElements(renderedCard, context, fragmentManager, cardLayout, adaptiveCard.GetBody(), channelAdaptor, hostConfig, renderArgs);
90117
}
91118
// Catches the exception as the method throws it for performing fallback with elements inside the card,
92119
// no fallback should be performed here so we just catch the exception
@@ -101,7 +128,7 @@ public View internalRender(RenderedAdaptiveCard renderedCard,
101128
Context context,
102129
FragmentManager fragmentManager,
103130
AdaptiveCard adaptiveCard,
104-
ICardActionHandler cardActionHandler,
131+
ChannelAdaptor channelAdaptor,
105132
HostConfig hostConfig,
106133
boolean isInlineShowCard,
107134
long containerCardId)
@@ -167,7 +194,7 @@ public View internalRender(RenderedAdaptiveCard renderedCard,
167194
// Render the body section of the Adaptive Card
168195
String color = hostConfig.GetBackgroundColor(style);
169196
cardLayout.setBackgroundColor(Color.parseColor(color));
170-
renderCardElements(renderedCard, context, fragmentManager, adaptiveCard, cardActionHandler, hostConfig, cardLayout, renderArgs);
197+
renderCardElements(renderedCard, context, fragmentManager, adaptiveCard, channelAdaptor, hostConfig, cardLayout, renderArgs);
171198

172199
if (hostConfig.GetSupportsInteractivity())
173200
{
@@ -191,14 +218,14 @@ public View internalRender(RenderedAdaptiveCard renderedCard,
191218
try
192219
{
193220
renderArgs.setRootLevelActions(!isInlineShowCard);
194-
View actionButtonsLayout = actionLayoutRenderer.renderActions(renderedCard, context, fragmentManager, cardLayout, primaryElementVector, cardActionHandler, hostConfig, renderArgs);
221+
View actionButtonsLayout = actionLayoutRenderer.renderActions(renderedCard, context, fragmentManager, cardLayout, primaryElementVector, channelAdaptor, hostConfig, renderArgs);
195222

196223
if (!secondaryElementVector.isEmpty())
197224
{
198225
IActionLayoutRenderer secondaryActionLayoutRenderer = CardRendererRegistration.getInstance().getOverflowActionLayoutRenderer();
199226
//if the actionButtonsLayout is not a viewGroup, then use cardLayout as a root.
200227
ViewGroup rootActionLayout = actionButtonsLayout instanceof ViewGroup ? (ViewGroup) actionButtonsLayout : cardLayout;
201-
secondaryActionLayoutRenderer.renderActions(renderedCard, context, fragmentManager, rootActionLayout, secondaryElementVector, cardActionHandler, hostConfig, renderArgs);
228+
secondaryActionLayoutRenderer.renderActions(renderedCard, context, fragmentManager, rootActionLayout, secondaryElementVector, channelAdaptor, hostConfig, renderArgs);
202229
}
203230
}
204231
// Catches the exception as the method throws it for performing fallback with elements inside the card,
@@ -215,7 +242,7 @@ public View internalRender(RenderedAdaptiveCard renderedCard,
215242
}
216243

217244
ContainerRenderer.setBackgroundImage(renderedCard, context, adaptiveCard.GetBackgroundImage(), hostConfig, cardLayout);
218-
ContainerRenderer.setSelectAction(renderedCard, renderedCard.getAdaptiveCard().GetSelectAction(), rootLayout, cardActionHandler, renderArgs);
245+
ContainerRenderer.setSelectAction(renderedCard, renderedCard.getAdaptiveCard().GetSelectAction(), rootLayout, channelAdaptor.getCardActionHandler(), renderArgs);
219246

220247
return rootLayout;
221248
}

source/android/adaptivecards/src/main/java/io/adaptivecards/renderer/BaseActionElementRenderer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,26 @@ public static class ActionOnClickListener implements View.OnClickListener
8383
* @param fragmentManager
8484
* @param viewGroup
8585
* @param baseActionElement
86-
* @param cardActionHandler
86+
* @param channelAdaptor
8787
* @param hostConfig
8888
*/
8989
public ActionOnClickListener(RenderedAdaptiveCard renderedCard,
9090
Context context,
9191
FragmentManager fragmentManager,
9292
ViewGroup viewGroup,
9393
BaseActionElement baseActionElement,
94-
ICardActionHandler cardActionHandler,
94+
ChannelAdaptor channelAdaptor,
9595
HostConfig hostConfig,
9696
RenderArgs renderArgs)
9797
{
98-
this(renderedCard, baseActionElement, cardActionHandler);
98+
this(renderedCard, baseActionElement, channelAdaptor.getCardActionHandler());
9999

100100
m_isInlineShowCardAction = (baseActionElement.GetElementType() == ActionType.ShowCard) && (hostConfig.GetActions().getShowCard().getActionMode() == ActionMode.Inline);
101101

102102
// As SelectAction doesn't support ShowCard actions, then this line won't be executed
103103
if (m_isInlineShowCardAction)
104104
{
105-
renderHiddenCard(context, fragmentManager, viewGroup, hostConfig, renderArgs);
105+
renderHiddenCard(context, fragmentManager, viewGroup, channelAdaptor, hostConfig, renderArgs);
106106
}
107107
}
108108

@@ -172,12 +172,12 @@ private void resetSeparatorVisibilities(ViewGroup viewGroup)
172172
}
173173
}
174174

175-
private void renderHiddenCard(Context context, FragmentManager fragmentManager, ViewGroup viewGroup, HostConfig hostConfig, RenderArgs renderArgs)
175+
private void renderHiddenCard(Context context, FragmentManager fragmentManager, ViewGroup viewGroup, ChannelAdaptor channelAdaptor, HostConfig hostConfig, RenderArgs renderArgs)
176176
{
177177
ShowCardAction showCardAction = Util.castTo(m_action, ShowCardAction.class);
178178

179179
m_invisibleCard = AdaptiveCardRenderer.getInstance().internalRender(m_renderedAdaptiveCard, context, fragmentManager, showCardAction.GetCard(),
180-
m_cardActionHandler, hostConfig, true, renderArgs.getContainerCardId());
180+
channelAdaptor, hostConfig, true, renderArgs.getContainerCardId());
181181
m_invisibleCard.setVisibility(View.GONE);
182182
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
183183
layoutParams.setMargins(0, Util.dpToPixels(context, hostConfig.GetActions().getShowCard().getInlineTopMargin()), 0, 0);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.adaptivecards.renderer
2+
3+
import io.adaptivecards.renderer.actionhandler.ICardActionHandler
4+
import io.adaptivecards.renderer.typeaheadsearch.IChoicesResolver
5+
6+
class ChannelAdaptor private constructor(builder: Builder) {
7+
val cardActionHandler: ICardActionHandler?
8+
val choicesResolver: IChoicesResolver?
9+
10+
init {
11+
this.cardActionHandler = builder.cardActionHandler
12+
this.choicesResolver = builder.choicesResolver
13+
}
14+
15+
class Builder {
16+
var cardActionHandler: ICardActionHandler? = null
17+
private set
18+
var choicesResolver: IChoicesResolver? = null
19+
private set
20+
21+
fun actionHandler(cardActionHandler: ICardActionHandler) = apply { this.cardActionHandler = cardActionHandler }
22+
fun choicesResolver(choicesResolver: IChoicesResolver) = apply { this.choicesResolver = choicesResolver }
23+
fun build() = ChannelAdaptor(this)
24+
}
25+
}

source/android/adaptivecards/src/main/java/io/adaptivecards/renderer/IActionLayoutRenderer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@
99

1010
import io.adaptivecards.objectmodel.BaseActionElementVector;
1111
import io.adaptivecards.objectmodel.HostConfig;
12-
import io.adaptivecards.renderer.actionhandler.ICardActionHandler;
1312

1413
public interface IActionLayoutRenderer {
1514
public View renderActions(RenderedAdaptiveCard renderedCard,
1615
Context context,
1716
FragmentManager fragmentManager,
1817
ViewGroup viewGroup,
1918
BaseActionElementVector baseActionElementList,
20-
ICardActionHandler cardActionHandler,
19+
ChannelAdaptor channelAdaptor,
2120
HostConfig hostConfig,
2221
RenderArgs renderArgs) throws AdaptiveFallbackException;
2322
}

source/android/adaptivecards/src/main/java/io/adaptivecards/renderer/IBaseActionElementRenderer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import android.view.ViewGroup;
88
import android.widget.Button;
99

10-
import io.adaptivecards.renderer.actionhandler.ICardActionHandler;
1110
import io.adaptivecards.objectmodel.BaseActionElement;
1211
import io.adaptivecards.objectmodel.HostConfig;
1312

@@ -19,7 +18,7 @@ Button render(
1918
FragmentManager fragmentManager,
2019
ViewGroup viewGroup,
2120
BaseActionElement baseActionElement,
22-
ICardActionHandler cardActionHandler,
21+
ChannelAdaptor channelAdaptor,
2322
HostConfig hostConfig,
2423
RenderArgs renderArgs) throws AdaptiveFallbackException;
2524
}

source/android/adaptivecards/src/main/java/io/adaptivecards/renderer/IBaseCardElementRenderer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import io.adaptivecards.objectmodel.BaseCardElement;
1313
import io.adaptivecards.objectmodel.HostConfig;
14-
import io.adaptivecards.renderer.actionhandler.ICardActionHandler;
1514

1615
public interface IBaseCardElementRenderer
1716
{
@@ -21,7 +20,7 @@ View render(
2120
@NonNull FragmentManager fragmentManager,
2221
@NonNull ViewGroup viewGroup,
2322
@NonNull BaseCardElement baseCardElement,
24-
ICardActionHandler cardActionHandler,
23+
ChannelAdaptor channelAdaptor,
2524
@NonNull HostConfig hostConfig,
2625
@NonNull RenderArgs renderArgs) throws Exception;
2726
}

0 commit comments

Comments
 (0)