I'm programming an app using android studio. I want to know in which way I can do a tutorial that users will see only the first time that use the app. Tutorial like image or screenshoots
Can someone help me? Thanks
I encountered this thread while looking for a solution for running a tutorial only at the first time (as rbaleksandar suggested), so in case it will be helpful for someone someday, here's a template of a solution that works for me (using the SharedPreferences API):
#Override
protected void onResume() {
super.onResume();
String tutorialKey = "SOME_KEY";
Boolean firstTime = getPreferences(MODE_PRIVATE).getBoolean(tutorialKey, true);
if (firstTime) {
runTutorial(); // here you do what you want to do - an activity tutorial in my case
getPreferences(MODE_PRIVATE).edit().putBoolean(tutorialKey, false).apply();
}
}
EDIT - BONUS - If you're into app tutorial - I'm messing now with the ShowcaseView library (which is amazing - try it out). Apparently they have some shortcut for that issue using a method called singleShot(long) - its input is a key for the SharedPreferences, and it does the exact same thing - runs only in the first activation. Example of usage (taken from here):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_shot);
Target viewTarget = new ViewTarget(R.id.button, this);
new ShowcaseView.Builder(this)
.setTarget(viewTarget)
.setContentTitle(R.string.title_single_shot)
.setContentText(R.string.R_string_desc_single_shot)
.singleShot(42)
.build();
}
You could always code your own solution, but, let us not reinvent the wheel.
Check this Android Library:
Tour Guide Repository
It allows you to add pointers in your screen, so the user knows where is he supposed to touch next.
It's pretty easy to use, you only need to point to the element you want the user to touch.
From the doc:
Let's say you have a button like this where you want user to click on:
Button button = (Button)findViewById(R.id.button);
You can add the tutorial pointer on top of it by:
TourGuide mTourGuideHandler = TourGuide.init(this).with(TourGuide.Technique.Click)
.setPointer(new Pointer())
.setToolTip(new ToolTip().setTitle("Welcome!").setDescription("Click on Get Started to begin..."))
.setOverlay(new Overlay())
.playOn(button);
Hope this helps!
Some links to libraries for creating introduction and/or tutorial screens.
Horizontal cards like Google Now:
https://github.com/PaoloRotolo/AppIntro
Tutorial screen:
https://github.com/amlcurran/ShowcaseView
As far as I understand the question is not How do I create a tutorial? (as the people who have already posted an answer have concluded) but instead How to show a tutorial upon first launch only?. So here are my two cents on this topic:
I'm not familiar with how your Android app stores its configuration data but I will assume that it's either in a database (SQLite) or a text file (plaintext, YAML, XML - whatever). Add a configuration entry to wherever the app's settings are being stored - something like tutorial_on : false, tutorial_on : 1 etc. depending on the format the configuration is represented in.
The way configurations work is that whenever an app (or software in general) is launched it has to be loaded in the app itself. So add the following to your app (where and how is up to you and your app design):
Check tutorial_on entry
If tutorial_on is set to true/1 whatever
2.1 Display tutorial
2.2 Change tutorial_on to false/0 whatever
2.3 Store the result in your configuration
Continue using the app
By doing so the first time your app launches the flag responsible for displaying the tutorial will be toggled and afterwards every time you start the app the toggle flag will be read leading to omitting the tutorial.
Personally I would suggest that you an option similar to Don't show tutorial anymore along with a description how to re-enable it (by triggering some action in that app's menu etc.). This has two major benefits:
Improved user experience - users like to have control (especially over trivial matters such as showing or hiding a tutorial). Whenever you take the control away from them, they get pissed off.
Enable your user to re-learn forgotten things - a general rule of thumb is to create apps that should not burden the user with a lot of stuff to remember. That is why things should be self-explanatory. However sometimes you may want to do that nonetheless. By adding the possibility that the user re-launches (by simply resetting the tutorial_on flag and repeating the steps from above) the tutorial allows just that - refreshing a user's memory.
Related
I'm newbie and I need help I can't resolve problem i don't know what to do. Very confusing it and need help (if you explain about it i'm very very thank you).
I watching Kotlin Project - Kotlin Android Instagram Clone using Firebase - Kotlin Instagram Clone
He using ArthurHub/Android-Image-Cropper (but it is old version right ?), I find some new version is CanHub/Android-Image-Cropper.
CropImage.activity()
.setAspectRatio(1,1)
.start(this#AccountSettingsActivity)
I can't use this code and i don't know how to resolve this problem, be utterly mystified.
Help me please Thank you very much.
Best regards.
(you can blame me, but not harsh i'm Newbie and I don't know)
I need help I can't resolve problem i don't know what to do. Very confusing it and need help
Since you said you're new I'll help you understand what the project page's example usage is showing you. I can only do this in general, I don't have time to go actually creating an example project to test it myself.
If you run into any issues, you'll have to puzzle it out - that's a big part of coding! It's rare that you'll get a nice simple solution that drops neatly into whatever you're doing, and learning how to make it work for you is an important skill to develop.
If you're ever stuck, always look at the project page (in this case the Github page) for a user guide, and they have a sample project in the repository too, so you can see how it works inside a full app. Don't be afraid to look at it, even if you don't understand it all - the more you do this the more you'll understand
Anyway, here are their examples:
Calling crop directly
class MainActivity {
private val cropImage = registerForActivityResult(CropImageContract()) { result ->
if (result.isSuccessful) {
// Use the returned uri.
val uriContent = result.uriContent
val uriFilePath = result.getUriFilePath(context) // optional usage
} else {
// An error occurred.
val exception = result.error
}
}
I'm going to break the code up here - this first bit is showing you're doing this inside an Activity. You're creating a cropImage object, which is an Activity launcher provided by registerForActivityResult - you're going to call launch on that later to start your cropping Activity.
The lambda in the curly braces is the function that's going to run when you get a result back - this is where you actually do something with the cropped image. In this case they're getting URIs to the image - I don't know what you need, but you can google "get bitmap from URI" or whatever if you need something else.
This whole getResultFromActivity thing is part of the AndroidX Activity and Fragment libraries - if you want to do it this way, you'll need those (and it's a good idea to use them on every project anyway, AndroidX stuff gives you backwards compatibility and saves you work).
Once you've set that up, you can call launch on cropImage to open your cropping Activity. It looks like they're giving you three examples, with different options (you could combine the options, but you only call launch once):
private fun startCrop() {
// Start picker to get image for cropping and then use the image in cropping activity.
cropImage.launch(
options {
setGuidelines(Guidelines.ON)
}
)
They're putting these in a startCrop() function you can call from, say, a button click listener. This one's setting some guideline options on the launched Activity - and like the comment says, it opens an image picker so the user can select an image.
// Start picker to get image for cropping from only gallery and then use the image in cropping activity.
cropImage.launch(
options {
setImagePickerContractOptions(
PickImageContractOptions(includeGallery = true, includeCamera = false)
)
}
)
This one (again, like the comment says - this stuff is there to help you) is setting some options on the picker instead, specifically limiting the choice to gallery images.
// Start cropping activity for pre-acquired image saved on the device and customize settings.
cropImage.launch(
options(uri = imageUri) {
setGuidelines(Guidelines.ON)
setOutputCompressFormat(CompressFormat.PNG)
}
)
This one does a few things: passes the URI of an image to crop (instead of opening a picker for the user to choose), adds guidelines, and sets the output format for the resulting cropped image.
Remember, these are all examples of the different ways you might use this. You can combine options, depending on how you want to configure things - you're setting options before you launch the cropping Activity.
Using CropView
This one looks like it uses a custom View you can add to a layout, which lets you crop an image:
// Add CropImageView into your activity
<!-- Image Cropper fill the remaining available height -->
<com.canhub.cropper.CropImageView
android:id="#+id/cropImageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
So you add this to your Activity's layout (might work on Fragments too, maybe with some tweaking - I'm not testing it remember!). The sizing isn't important - you can work out how to make a view as big as you want it to be. It's just a normal View in a layout.
//Set image to crop
cropImageView.setImageUriAsync(uri)
// Or prefer using uri for performance and better user experience.
cropImageView.setImageBitmap(bitmap)
In the Activity, with a reference to the CropImageView in your layout, you call this set image function with the URI of an image you want to use. Or, if you have it, you can set a Bitmap directly. Once it's set on the CropImageView, the user can adjust it
// Subscribe to async event using cropImageView.setOnCropImageCompleteListener(listener)
cropImageView.getCroppedImageAsync()
// Or.
val cropped: Bitmap = cropImageView.getCroppedImage()
Now this one's a bit trickier - to me, it's not completely obvious how you're supposed to use that first one. So let's actually look at the code in CropImageView, where we can see how it works and read the documentation.
Surprise! There is no getCroppedImageAsync() function, just a croppedImageAsync one (without the get) that looks like it does the same thing. That's fine. If you're using an IDE like Android Studio, it'll probably suggest the right function as you type, and you can read the documentation right there:
* Cropped image based on the current crop window to the given uri.
* The result will be invoked to listener set by [setOnCropImageCompleteListener].
Ok, that looks like what the example is hinting at. You call setOnCropImageCompleteListener with a function to do something with the resulting image, like this:
cropImageView.setOnCropImageCompleteListener { view, result ->
// do something with cropped result
}
and then you call croppedImageAsync (with whatever option parameters you want, check the docs) to start the crop-and-store process. When it's done, that callback function you just set will be called with the result.
And then there's the custom Activity example but that's enough for me - if you really want that, if you can follow what we've gone over so far you should be able to work out the rest.
Since you're already making an app following a tutorial, and it's using a different library (with a different way of doing things) you'll have to work out how to fit this library into your own project. Take a step back and look at what you're doing in the tutorial, what you're trying to achieve (like launching a cropping Activity), and work out how you'd achieve the same task in this library.
A lot of software development is about trying to fit different pieces together like this, and it rarely goes smoothly. Not knowing what you're doing is normal! But then you have to sit down and work it out. Hopefully that gives you an idea of an approach you can take to learning - and there is a lot to learn at first!
I have 2 buttons first button has this id id="#+id/button_A" and second button has this id id="#+id/button_B"
button_A I named it text="areNotificationsEnabled ( On )"
button_B I named it text="canDrawOverlays ( Off )"
I want when the user block or unblock app notification, So update button_A to On or Off. Same thing with button_B.
I can solve the problem using onResume but there is exceptions like the user can block notification from status bar without leave the app or using split screen to turn on or off canDrawOverlays
I solved the problem using CountDownTimer and make check every 250 milliseconds but I think it's not good way to do that, What about onWindowFocusChanged or there is better way?
As far as i know this is not possible in the traditional view system.
However, it is possible with Jetpack Compose, Accompanist & some experimental api - see Accompanists Github for details and the android docs for how to implement it in traditional view systems
//inside a composable
val cameraPermissionState = rememberPermissionState(android.Manifest.permission.CAMERA)
Text("camera permission enabled = ${cameraPermissionState.hasPermission}")
While this solution will work "just fine" it might come with a pretty steep learning curve. I suggest you go this route only if you intend to start using compose anyhow.
I am learning Android programming, this seems to be a silly question.
pd = new ProgressDialog(this);
pd.setCancelable(false);
Cancelable can be
true
false
default behavior / not set
Is there an easy way to know the default behavior is either true or false?
In android Studio editor, use ctrl + Q, got this:
Online reference does not help either. setCancelable
I can run the code, then know the result, but it gotta be a easy way, right?
Take a look into its parent class: Dialog.
You can find out this line
/**
* This field should be made private, so it is hidden from the SDK.
* {#hide}
*/
protected boolean mCancelable = true;
By the way ProgressDialog it's not recommend by Google. You should use ProgressBar instead. You have to handle block button or something like this while ProgressBar is showing, but it bring user a better UX
You can control + click (on Android Studio or Eclipse) on the class that interests you and see on the library's source whether the boolean flag is set upon initialization on the class.
Usually, the information would be on the online reference. However, as you point out, it isn't!
Whenever I find I need to know something like that, and it isn't documented, then I check the source code. It is usually quite trivial to search for the specific class source in Google.
This of course, is only showing the value it takes by default for Android 4.4. In this case though, the value is unlikely to have a changed default. You should always bear that possibility in mind.
Maybe this question has been ask already, but could not find any answer for almost 2hours of internet search.
There is a graphical UI designer wich is coming along with the last android SDK.
Looks pretty cool and well done.
Nevertheless I * cannot find how to attach an event to the control through the graphical editor.
Of course I can add it manually into the xml, but in that case, what's the purpose of having such tool without that function ?
I mean all the other SDK I had in other languages always include that function.
I've also not been able to find doc about how to use this tool. Quite sad...
Thanks
If you want to add a click event handler, select the button (widget) in the GUI that you want to listen for, and look for the property onClick. Enter the name of the method you want to call when the user clicks on that widget, like.. onMyButtonClick
Then add the method to your Activity
public void onMyButtonClick(View v) {
// I heard the button click
}
The GUI builder is getting there, and is not yet as easy to use as the one in XCode, but it's not hard when you get used to it.
I want to know is there any method or any link or tutorial to perform redo undo operation in Android edittext. If any one knows than please let me know.
Quick note on the Antti-Brax/Divers(Kidinov) solution. It works great, except if you try to use it with a TextView post-API 23, you'll run into problems, because guess-what, Google actually added a hidden UndoManager (android.content.UndoManager) and didn't document it or make it obvious it was there. But if you have a hard/bluetooth keyboard in Marshmallow or Nougat and hit ^Z or SHIFT-^Z, you'll get undo/redo.
The problem comes if you're already using Antti-Brax's class with an EditText, and you also hook it to ^Z and shift-^Z, you'll run into problems with anyone using a hard keyboard. Namely the ^Z will trigger BOTH the native and Antti-Brax's undo, leading to two undos simultaneously, which isn't good. And after a few of them, you'll probably get a Spannable out of bounds crash.
A possible solution I found is to subclass the TextView/TextEdit/whatever and intercept the undo/redo calls from the TextView so they don't run as follows:
#Override
public boolean onTextContextMenuItem(int id) {
int ID_UNDO, ID_REDO;
try {
ID_UNDO = android.R.id.undo;
ID_REDO = android.R.id.redo;
} catch (Resources.NotFoundException e) {
ID_UNDO = 16908338; // 0x1020032
ID_REDO = 16908339; // 0x1020033
}
return !((id == ID_UNDO) || (id == ID_REDO)) && super.onTextContextMenuItem(id);
}
Those magic id numbers were found here, and are used only as a backup if the android.R.id.undo values aren't found. (it also might be reasonable to assume that if the values aren't there the feature isn't there, but anyway...)
This is not the best solution because both undo trackers are still there and both are running in the background. But at least you won't trigger both of them simultaneously with ^Z. It's the best I could think to do until this gets officially documented and the getUndoManager() methods of TextView is no longer hidden...
Why they made a feature you can't turn off (or even know if it was there or not) "live" in released Android I can't say.
I just opened an issue on Android's issue tracker if anyone wants to follow this.
There is an implementation of undo/redo for Android EditText in
http://credentiality-android-scripting.googlecode.com/hg/android/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptEditor.java
The code works but does not handle configuration changes properly. I am working on a fix and will post here when it is complete.
My Google search was :-
android edittext onTextChanged undo
I know this is an old question, but as there is no accepted answer, and this is an issue I've tackled myself from many angles, I'd like to add my solution in case it helps anyone. My answer is probably most relevant to large (1,000words+) volumes of text editing apps that require this feature.
The simplest way to resolve this problem is to make periodic copies of all text on screen, save it to an array and call setText() every time the Undo method is called. This makes for a reliable system, but it isn't ideal for large (i.e. 1,000words+) text editing apps. This is because it:
Is wasteful. It could be that only one word changes in a two thousand word document, so that's one thousand, nine hundred and ninety nine words needlessly committed to memory.
Can lead to performance issues, as some low-tier hardware struggles with rendering large amounts of text. On some of my test devices, this method can lead to freezes of a few seconds whenever Undo is called.
The solution I currently use is comparatively complex, but I've published the results in a library here.
Essentially, this library saves a copy of text as soon as a user begins typing, and then another copy of text once they've stopped typing for a set amount of time (in my case, two seconds). The two text strings are then compared, and the altered section of text returned, the indexes where the alterations occured, and details on whether or not the change was an addition of new text, a deletion, or a replacement of old text with new text.
The net result is that only the necessary text is saved, and when Undo is called, there is only a local delete(), replace() or insert() call, which makes for much faster operations on large text fields.
Here is the undo/redo implementation that was linked to from Gary Phillips' answer extracted into a reusable and universal undo/redo plugin for any widget that descends from a TextView. I added some code for persisting the undo history.
http://code.google.com/p/android/issues/detail?id=6458#c123
Hope this helps.
To preserve EditText Styling with regards to undo:
You can create an ArrayList<EditText> or ArrayList<String> (String containing html text) to store your last 10 (for example) actions. So ArrayList [0] would contain html text from your first action and ArrayList [9] would contain html text from your very last action. Each time the user taps "undo" in your app, you would apply ArrayList [size()-1] to your EditText and then remove ArrayList [size()-1] from your Array.