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!
Related
I have written UI test to test a journey of a feature of an app. When I navigate to next screen but android can't find any tag as it is building the UI.
So, for this I had to use Thread.sleep(timeinmillis). But I know it is not a proper way.
Therefore, I came to know about waitUntil {// condition}. But this only work when tag exist in the semantic tree.
How can I wait for a testTag that is not currently available on the tree but will eventually come after some millis time.
............
In this blog post they have described how to use waitUntil for a loader. But in compose if I use loader like this below it can't find the loader tag. It shows error saying there is no tag with this name
if(isLoading)
// ShowLoader()
I'm new to kotlin and android app developpement in general and I want to make a Quiz app with jetpack compose not XML, and this app has multiple levels and when the user starts the quiz if he decides to stop playing in a certain level and quit the app i want to save that level so next time when he come back to play he's gonna start from the same level he stopped.
I've tried to use preference datastore but it doesn't seem to work.
this is my Datastore class:
Datastore
this is how I store the current level:
save current lvl
this is how I get the lvl I stored in the datastore:
get stored lvl
if you have any idea what I'm doing wrong please and if posibile use jetpack compose.
thank you.
You should post code, not images. Although in this case, you can see from your second image that saveScreen is a function you're never calling anywhere, because it's grey (i.e. it's never used anywhere), and there's a yellow underline giving you a warning too.
You'll have to call saveScreen() or saveScreen.invoke() somewhere. Why not just make it a normal function though?
// call this when you want to save the screen
private fun saveScreen() {
// scope.launch { datastore.Save etc }
}
Unless doing things this way is a Compose thing (I've never used it). Either way, that function you're defining isn't called anywhere, so your screen isn't being stored!
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.
I'm not sure SO is the right place to ask this question so let me know if I should maybe post it on ProgrammersSE.
I've got an Android library project which comes with some functionality and some basic XML files. In the nearest future I'll be developing multiple apps which will heavily depend on that library - it's possible that some of them will only differ in that they'll be using different XML layout files and image resources. As far as I know Android will automatically pick the ones from the regular projects instead of the library one if the names of the appropriate files are the same so this shouldn't be a problem.
The problem is I expect that some of the projects will have to have a slightly extended functionality - meaning I'd have to, e.g., extend the classes which are in the library project.
I just tried that out but obviously that didn't work as I wasn't overriding the entire code of a class - just adding to it, meaning I seemingly can't have the the library Activities call the classes from my regular project.
Is there any way around that without using reflection?
Is there maybe a better way of handling such a situation?
Edit for clarification:
Thanks to #jucas and #Alex Cohn for the answers and the links. I'm not sure if the solutions you wrote are applicable to my situation - I'd probably have to see examples of those coded to decide if I can do anything similar in my project.
Here's an example of what makes this problematic for me: say in my library project I've got a class called MyActivity which extends Activity and implements OnScrollChangedListener because there's a ScrollView in it whose background has to scale. There could be something like this in it:
#Override
public void onScrollChanged() {
int currentScrollOffsetY = this.scrollView.getScrollY();
// No case for further back than the bottom of the screen (lower than 0)
// and if it's higher than where it should stop, keep it at that point
if (currentScrollOffsetY > this.screenHeightPx * MULTIPLIER_Y_ANIMATION_STOP) {
currentScrollOffsetY = (int) (this.screenHeightPx * MULTIPLIER_Y_ANIMATION_STOP);
}
// Set the pivot points of the background images
this.imageBackground.setPivotX(this.imageBackground.getWidth() / 2.0f);
this.imageBackground.setPivotY(0);
// Scale the background
float newBackgroundScale = 1 - (float) currentScrollOffsetY / (float) this.screenHeightPx;
if (newBackgroundScale < 0.75f) {
newBackgroundScale = 0.75f;
}
this.imageBackground.setScaleX(newBackgroundScale);
this.imageBackground.setScaleY(newBackgroundScale);
}
As you can see, the new scale for the background image is never smaller than 0.75 of the original size. Now if one of the projects using the library project needed that to be 0.8 instead, I could just move the value from the code to the XML values resources and it should be dynamically read from there - that's perfectly fine.
But what if I not only wanted to do that but also scale another ImageView?
this.imageBackground.setScaleX(newBackgroundScale);
this.imageBackground.setScaleY(newBackgroundScale);
this.differentImageBackground.setScaleX(newBackgroundScale);
this.differentImageBackground.setScaleY(newBackgroundScale);
How could this be achieved? I'm sorry if I don't understand this straight away - I've never done anything like this yet and some concepts are a bit difficult for me to get my head around them.
This a very common problem, and one that has several answers that might or might not be the best for your particular case, here are 2 from the top of my mind:
Develop a plugin architecture for your app, to load content and functionality from plugins Plugins architecture for an Android app?, note that this might be overkill if you just need to change a few classes here and there.
Modify your library project's architecture: This is one that I tend to use the most, just because it is simply and doesn't require a very complex refactoring. The steps needed for this are usually like this:
a. Figure out which parts of your activity or fragment might need to be extended by your main app project
b. Create interfaces and classes that implement those interfaces for the extendable functionality
c. This is the tricky part, isolate the creation and use of those classes in specific methods inside your activities or fragments
d. Finally on your main app project, create new classes that implement the same interfaces and override your fragments or activites to create these classes instead
I hope this helps you a bit, and if it doesn't you might want to sketch out some code in order to see exactly what problems you are having
This looks like a good fit for "inversion of control" design pattern. If a ExtendsActivity class is not changed between projects, but sometimes it uses an actor of class MyActor and sometimes ExtendsMyActor, then you should prepare a way for ExtendsActivity to accept the reference to such actor. You can inject this reference on construction, or later during the lifecycle of activity.
It is often recommended to use interface, i.e. define IActor and have both MyActor and any alternative implements this interface. But in some cases, extends fits perfectly, too.
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.