25 May 2020
Getting a result from a Fragment
is almost identical to the startActivityForResult
, setResult
, and onActivityResult
combo.
In the 1.3.0-alpha04 version of the AndroidX Fragment library, Google introduced new APIs that allow passing data between Fragment
s.
Added support for passing results between two Fragments via new APIs on FragmentManager. This works for hierarchy fragments (parent/child), DialogFragments, and fragments in Navigation and ensures that results are only sent to your Fragment while it is at least STARTED. (b/149787344)
Thanks to the Fragment Result API, FragmentManager
gained two new methods:
How to use it?
In FragmentA
, set up FragmentResultListener
in the onCreate
method:
setFragmentResultListener("request_key") { requestKey: String, bundle: Bundle ->
val result = bundle.getString("your_data_key")
// do something with the result
}
In FragmentB
, add this code to return the result:
val result = Bundle().apply {
putString("your_data_key", "Hello!")
}
setFragmentResult("request_key", result)
Start FragmentB
e.g. by using:
findNavController().navigate(NavGraphDirections.yourActionToFragmentB())
To close / finish FragmentB
call:
findNavController().navigateUp()
Now, your FragmentResultListener
will be notified, and you will receive your result.
You can use other methods to achieve something similar:
* I’m using fragment-ktx
to simplify the code above.
02 Aug 2019
Recently I successfully flashed ACRO firmware into my JJRC H67. It wasn’t easy, but I will show you how you can do it.
To do the whole procedure, you will need:
- ST-LINK V2,
- ST-LINK Utility app,
- and some cables.
Then you go through the steps listed on the RCGroups forum, but instead of BoldClash-BWHOOP-B-03 precompiled firmware, you will use this binary. It is a compiled Silverware by NotFastEnuf with the following config:
#define BWHOOP
#define RX_BAYANG_PROTOCOL_TELEMETRY_AUTOBIND
#define USE_MULTI
// #define ARMING CHAN_5
If you are a Mac user, you are going to do some steps differently. You will need Silverware Tools for macOS since ST-LINK Utility is Windows-only software.
- in step “Erasing the factory firmware” instead of ST-LINK Utility user Unlocker to unlock the chip on your flight controller,
- in step “Flashing a new firmware” use the Flasher app. You just drag and drop your firmware file (e.g.:
h67.hex
) into the app’s window.
After this whole procedure, you will be able to bind to your Taranis as I described here.
I also gathered some additional materials you may find useful:
Happy flying!
24 Jul 2019
Configuring Taranis Q X7 with the Multiprotocol TX module is pretty straightforward:
- go to the
MODELSEL
setting,
- select an empty row and click
Create model
,
- click
PAGE
and assign a Model name
,
- scroll to the bottom until you find
Internal RF
setting,
- set
Mode
to OFF
,
- go to the
External RF
and set Mode
to PPM
,
Ch. Range
set to CH1-12
,
- go to the
MIXER
screen by clicking the PAGE
button,
- set
CH1
to 100 Ail
,
- set
CH2
to 100 Ele
,
- set
CH3
to 100 Thr
,
- set
CH4
to 100 Rud
,
- now you are ready to go :).
Turn off your Taranis and power on your JJRC drone. Now, hold your sticks in the following positions:
H36
- left stick – bottom-right position
- right stick – bottom-right position
H67
- left stick – bottom position
- right stick – top-right position
and power on your radio. When JJRC binds, it stops blinking.
Happy flying!
29 Mar 2016
As we know, some HTML tags are not supported by the Html
class. What can we do about it? Android SDK provides a TagHandler
interface that allows us to handle unsupported tags.
Now let’s add <strike />
tag to our lorem string from the previous post.
<string name="lorem"><![CDATA[<b>Lorem ipsum dolor</b> sit <u>amet</u>, consectetur <font color="green">adipiscing</font> elit. <i>Cras ut magna eget erat fermentum dignissim.</i> Aenean interdum ultrices sapien<sup>1</sup>. <font color="red">Vestibulum feugiat ultrices neque, vel pretium massa. Etiam tempor luctus dui eget aliquam.</font> <strike>In nec metus sit amet orci facilisis pretium.</strike>]]></string>
When we use the fromHtml
method with one parameter and run the code, we can see that it doesn’t work as intended.
Because <strike />
is not supported, we have to create TagHandler
implementation. As ImageGetter
, this interface also has only one method which notifies us when an unsupported tag is found:
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader);
It is the implementation of the TagHandler
interface with <strike />
support:
class StrikeTagHandler implements Html.TagHandler {
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("strike")) {
processStrike(opening, output);
}
}
private void processStrike(boolean opening, Editable output) {
int length = output.length();
if (opening) {
startStrike(output, length);
} else {
endStrike(output, length);
}
}
private void startStrike(Editable output, int length) {
output.setSpan(new StrikethroughSpan(), length, length, Spannable.SPAN_MARK_MARK);
}
private void endStrike(Editable output, int length) {
Object obj = getLast(output, StrikethroughSpan.class);
int where = output.getSpanStart(obj);
output.removeSpan(obj);
if (where != length) {
output.setSpan(new StrikethroughSpan(), where, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
private Object getLast(Editable text, Class kind) {
Object[] objs = text.getSpans(0, text.length(), kind);
if (objs.length == 0) {
return null;
} else {
for (int i = objs.length; i > 0; i--) {
if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) {
return objs[i - 1];
}
}
return null;
}
}
}
This code is from Android: How to use the Html.TagHandler? StackOverflow question.
When an unsupported tag is detected, the handleTag
method is triggered. We use this signal to start and finish processing this tag.
When the opening
parameter is true
, we mark a start of a struck-out text by using the setSpan
method with Spannable.SPAN_MARK_MARK
.
Next, when the end tag is detected (opening
is false
), we search for the last StrikethroughSpan
with Spannable.SPAN_MARK_MARK
flag to find start position. Then we use length
as our end position.
Finally, we apply StrikethroughSpan
by calling:
output.setSpan(new StrikethroughSpan(), where, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
It is how we use our StrikeTagHandler
:
TextView textView = (TextView) findViewById(R.id.lorem);
String string = getString(R.string.lorem);
Spanned spanned = Html.fromHtml(string, null, new StrikeTagHandler());
textView.setText(spanned);
Below we can see the result:
19 Mar 2016
The Html
class supports images just like HTML. Let’s see how Html.fromHtml()
method handles them. In this blog post, I will show you how to use ImageGetter
to display images in the TextView
.
First, we need to add <img src="..." />
tag to our HTML string. Next, we see what happens, but we encounter the following problem:
Why was such a square displayed? It’s fromHtml()
default behavior, it uses com.android.internal.R.drawable.unknown_image
drawable when we don’t pass an ImageGetter
object to this method. What is the ImageGetter
? It’s an interface with one method getDrawable(String source)
which is used by the Html
class to retrieve Drawable
. We implement this interface when we want to support <img />
tags. source
argument is equal to src
attribute value. ImageGetter
’s getDrawable(String source)
is triggered by the Html
class everytime it encounters <img />
tag.
Now I will show you an example of how to use the ImageGetter
interface and load drawable based on src
attribute value.
public class ResourcesImageGetter implements Html.ImageGetter {
private Context context;
public ResourcesImageGetter(Context context) {
this.context = context;
}
@Override
public Drawable getDrawable(String source) {
String drawableName = source.substring(0, source.lastIndexOf('.'));
Drawable drawable = getDrawableByName(drawableName);
if (drawable != null) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
drawable.setBounds(0, 0, width, height);
}
return drawable;
}
private Drawable getDrawableByName(String name) {
Resources resources = context.getResources();
String packageName = context.getPackageName();
final int resourceId = resources.getIdentifier(name, "drawable", packageName);
return resources.getDrawable(resourceId);
}
}
The code is rather obvious. Based on the image name, I’m loading the application Drawable
resources (e.g. ic_launcher.png
will be replaced by drawable/ic_launcher.png
image).
As the documentation says, don’t forget to call setBounds()
on the Drawable
object:
Make sure you call setBounds() on your Drawable if it doesn’t already have its bounds set.
Below we can see the final result: