I have searched and found a lot of different answers for this question, but nothing quite settles it for me. Total android n00b, and I ask for your patience in advance.
I'm having trouble dealing with a FileChooser problem with Android KitKat. As per [here][1], and according to [Steve N][2] i get the impression that this file chooser problem is caused by my android version (4.4.2)
Given that filechooser isn't working, I want to implement a basic dialog. I'm going to check the android version number for the device, and then display a message, citing the current lack of support, if the version number comes back with a 4.4 in front.
At present, i'm just using toast
public boolean checkVersionSupport(){
if (Build.VERSION.RELEASE.equals("4.4.2") {
Toast toast = Toast.makeText(context, androidOS, duration);
toast.show();
}
}
Instead of toast, I'd like a simple, one button dialog box to open, with an OK button, which I will use to redirect the user out of the native app and off to chrome, where the whole file chooser thing seems to be working.
Couple of things that I have found difficult after reading through the android developer materials.
Do I need a layout XML file for the dialog box?
Where do I put the class file for the MyAlertDialogFragment class I am creating? Can it be anywhere in the java folder or does it have to be in a sub folder java/com.myproject... And what impact does that have for importing the class into my java activity file?
Can someone please explain where FragmentAlertDialog comes from in the Android Developer Materials.
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((**FragmentAlertDialog**)getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((**FragmentAlertDialog**)getActivity()).doNegativeClick();
}
}
)
.create();
}
}
What's best practice for icons? I see a debate going on about this, but for the simple purpose of having an icon at the top of a dialog, for one single basic usage, what would be the quickest way of getting it done? I'm just copying files into the res folder and referencing them... 48dp? This might be a whole different question.
Do I need a layout XML file for the dialog box?
That honestly depends on which type of Dialog you use.
The AlertDialog does not require a specified layout, all you need is to use AlertDialog.Builder() and set the positive/negative buttons, and how it handles that.
The DialogFragment onCreateDialog() method is the preferred way of using an AlertDialog. It also doesn't require an XML layout, but as such, its layout is still restricted to essentially a Yes/No option: look here for complete example
The DialogFragment onCreateView() method allows you to create a dialog from a specified layout XML. So if you wish to customize the view of the dialog beyond "title, description, yes/no", then yes, you need to specify the XML file for the dialog fragment, look here for an example, although the advice says you should look into ButterKnife and Otto libraries to make it even better.
Where do I put the class file for the MyAlertDialogFragment class I am creating? Can it be anywhere in the java folder or does it have to be in a sub folder java/com.myproject... And what impact does that have for importing the class into my java activity file?
Anywhere inside the project. Although I prefer to put it in something like <projectroot>/presentation/fragments/dialog, package-wise.
Can someone please explain where FragmentAlertDialog comes from in the Android Developer Materials.
FragmentAlertDialog is an assumed Activity from which the MyAlertDialogFragment dialog fragment is shown, and is assumed to have the methods doPositiveClick() and doNegativeClick(). The title int that is provided is most likely a string resource defined in /res/values/strings.xml which is used for localization. For example, R.string.fancy_title_name.
So it's something like this
public class FragmentAlertDialog extends AppCompatActivity {
#Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_fragment_alert_dialog);
//stuff
}
#Override
public void onPostResume() {
MyAlertDialogFragment madf = MyAlertDialogFragment.newInstance(R.string.something);
madf.show(getSupportFragmentManager(), "alert-dialog-fragment");
}
}
Otherwise, MyAlertDialogFragment just extends from DialogFragment and overrides onCreateDialog to create an AlertDialog inside this DialogFragment.
In case you'd ask, the newInstance() method is so that you would NOT use a parametrized constructor. Fragments should not have parametrized constructors, they ought to receive their data in the setArguments(Bundle) method.
What is the best practice for icons?
Refer to the material design guidelines.
Related
I'm new new in Java and working on an old project that uses bsImagePicker. There's a bug in my current project that when the user wants to click the below back button of the gallery it takes the user to home page.
This shouldn't be the default behavior, rather it should take the user 1 step back. Please, How do I overwrite the method of this back button? Unfortunately, I couldn't find any xml file that has referenced this button neither there's any previous overwritten method.
Thanks in advance.
Edit: I searched more and figured out maybe it has to do something with getSupportActionBar().setDisplayHomeAsUpEnabled() but I don't know how to set its android:parentActivityName attribute.
To override onBackPressed() method and implement your own functionality or behavior.
#Override
public void onBackPressed() {
//implement your own functionality in this
}
But since you are trying to implement it for back button shown in attached image and you don't have reference of it. Either you can create a reference by own or you can try on onCancelled method as provided in BSImagePicker gallary github repo.
//Optional
#Override
public void onCancelled(boolean isMultiSelecting, String tag) {
//Do whatever you want when user cancelled
}
I've built an android AlertDialog (named dialog) that fires other Android AlertDialog (named dialog2) if some conditions happen.
I've checked that what if only one of them is displayed on screen it is dismissed without any problem.
Problem comes when both of them are showing, that happens when I press the OK button for the second dialog, it just closes the second dialog, despite the first dialog is even showing on screen.
This is the code related to dialog2 for that operation:
dialog2.setOnShowListener(new DialogInterface.OnShowListener()
{
#Override
public void onShow(final DialogInterface dialog)
{
Button button = ((AlertDialog)
dialog).getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
[some more operations]
dialog2.dismiss();
dialog.dismiss();
}
});
}
});
The strangest thing is that if I supress the line dialog2.dismiss(); by leaving only dialog.dismiss(); what get dismissed is the second dialog, not the first one, looks like android somehow confuses one with the other, and I don't think that should be happening because they are created separately like this:
dialog=[code to create that dialog]
dialog2=[code to create that dialog]
Doing that the only way I see that app would close dialog2 when asked to close dialog would be doing dialog=dialog2, which I am not. I think They should be different objects loaded in memory each one with their characteristics.
I don't see any reason of why this is happening, seems like a clueless error from my point of view. Hope you can give ideas about what is happening.
A couple things to take note of here:
First, it isn't necessary to create an "onShowListener", unless you actually need to perform a task when the dialog is shown, this code should help you correctly create an AlertDialog:
new AlertDialog.Builder(getContext())
.setTitle(R.id.dialog_title)
.setMessage(R.id.dialog_message)
.setPositiveButton(R.id.positive_text, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//do onClick stuff here
}
})
.show();
This example does all your setup at once. If you need a reference to this dialog or don't want to show it right away, just use AlertDialog.Builder dialog1 = new ..., and then use dialog1.show() to create the dialog.
Second, the reason that only the second dialog is closing when you suppress dialog2.dismiss() is because there is a local variable named 'dialog' inside of your onShow() method (look at the method parameters) that is taking precedence over your broader scoped 'dialog' variable.
Third, to answer your actual question, can you dismiss the first dialog just before you show the second? I don't see any real reason to have 2 dialogs open at the same time.
I am very new to Java. I am doing a school project at the moment and I have my main activity, then I have a settings activity. I am trying to modify the xml from the main activity with the settings activity. I am able to modify the settings xml file with the settings.java, but I would like to modify the main activity xml with settings.java
public class Settings extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
// Get the Intent that started this activity and extract the string
Switch switchButton;
final RelativeLayout mRelativeLayout = (RelativeLayout) findViewById(R.id.activity_settings);
final RelativeLayout mRelativeLayoutMain = (RelativeLayout) findViewById(R.id.activity_main);
switchButton = (Switch) findViewById(R.id.switch1);
switchButton.setChecked(true);
switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean bChecked) {
if (bChecked) {
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
mRelativeLayout.setBackgroundColor(Color.GRAY);
} else {
mRelativeLayoutMain.setBackgroundColor(Color.WHITE);
mRelativeLayout.setBackgroundColor(Color.WHITE);
}
}
});
if (switchButton.isChecked()) {
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
mRelativeLayout.setBackgroundColor(Color.GRAY);
} else {
mRelativeLayoutMain.setBackgroundColor(Color.WHITE);
mRelativeLayout.setBackgroundColor(Color.WHITE);
}}
public void toast1(View view) {
android.widget.Toast.makeText(this, "Created by Cody Walls and Tommy Serfas", android.widget.Toast.LENGTH_LONG).show();
}
/*public void switch1(View view) {
ScrollView mScrollView = (ScrollView) findViewById(R.id.scrollView);
mScrollView.setBackgroundColor(Color.GRAY);
}*/
}
In the Code I am trying to change the background of the main activity xml with :
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
and when I run the app and click the intent it will crash with the error:
"java.lang.NullPointerException: Attempt to invoke virtual method
'void android.widget.RelativeLayout.setBackgroundColor(int)' on a null
object reference"
I think the easiest way is to create an PreferenceManager.SharedPreferences, in which I recommend you to store current app data. This will help you not to loose any changes in app after you exit the it. Here is short instructions:
Create button in settings activity which will change something in main activity.
Create onClickListener for your button.
Use .SharedPreferences to store was you button clicked or not. (I recommend storing boolean variables, this way you can store was button clicked or not.)
I both of your activities in onCreate method call .getSharedPreferences to read saved app values. (I mean to read was the button clicked or not.)
Use app values you got from 4. to change any element in activity. (For example if you stored that button was clicked, then change some TextView text or etc.)
I hope you understood the idea.
Link to the Android developer tutorial about App key values storing & saving
Link to the StackOverflow much easier explanation & examples
There are a couple of ways of doing this (Some of which depends on how you are switching back and forth from each activity). It also depends on what things you are changing.
From your settings page, as you are changing different settings, you'll save this content within Preferences. (You can see more how to use Preferences here: https://examples.javacodegeeks.com/android/core/ui/settings/android-settings-example/ or by just Googling it).
On you main activity, depending on how you come back to it (onStart most likely), you can setup the things you need to programmatically.
So, you may need to do a little research on the Android lifecycle and how each cycle works (https://developer.android.com/guide/components/activities/activity-lifecycle.html), how to program the UI programmatically through Java (http://startandroid.ru/en/lessons/220-lesson-16-creating-layout-programmatically-layoutparams.html), and the Preferences Android library to save certain settings.
The xml isn't meant to be "altered". You can change the UI programmatically. It's possible to build an Android app without any xml. When Android was first built, it didn't use the xml to create the UI. It was all done through Java. It was then added to use xml to create your activities or fragments or any UI component. This made things easier for more static activities or activities with very little dynamic content.
So the Negative and Positive buttons of my AlertDialog are greyed-out, but they shouldn't be.
greyed-out text screen
I suspect it has something to do with Context, becouse once i had identical problem with my ListView. I have repaired that by changing argument in ArrayAdapter's reference from getApplicationContext() to getBaseContext(). Can someone explain it to me? I don't really understand the 'Context'
This is my code
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("What do you want to do with " + getArrayList("ListOfRecipes").get(position) );
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
List<String> list = new ArrayList<>(getArrayList("ListOfRecipes"));
Toast.makeText(getBaseContext(), list.get(position) + "has been removed", Toast.LENGTH_SHORT).show();
list.remove(position);
saveList(list, "ListOfRecipes");
}
});
builder.setNegativeButton("Modify", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
List<String> list = new ArrayList<>(getArrayList("ListOfRecipes"));
SharedPreferences sp = getSharedPreferences("Recip", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("Recip", list.get(position));
editor.apply();
startActivity(new Intent(getBaseContext(), ManageRecipeActivity.class));
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
First of all, if that piece of code is inside an activity, you can simply declare context with "this" (which is what you have done by passing MainActivity.this) to the dialog builder.
What I'm suspecting is that it may be that your MainActivity is getting a theme for the AlertDialog that is making the buttons look gray. You could check that out in your styles.xml (if there is a style defined for the dialog) and in the AndroidManifest file for the theme you are passing to your MainActivity.
If you don't find anything wrong/don't want to change the theme, I can think of two ways to solve that problem.
First way - Changing the button color (less work, but less flexible)
The first is actually changing the dialog button color as it's done in this post to whatever color you want.
Second way - inflating a custom view that meets your needs (more work, but more flexible)
The second way would be to inflate a view and pass it to the dialog. Actually, you don't really have to use the standard dialog style at all, you can inflate your own view inside it to fit your needs.
To do that, you must:
1) Inflate a chosen view
As an example:
LayoutInflater factory = LayoutInflater.from(this);
final View view = factory.inflate(R.layout.image_dialog_layout, null);
2) Pass the inflated view to your dialog builder:
final AlertDialog dialog = new AlertDialog.Builder(this);
dialog.setView(view);
//Additional code to set click listeners, i.e.
dialog.create().show();
}
That way, you'll be inflating whatever layout you want, so you can just put the buttons you want inside it (with the color, size, font type you want).
It is important to notice that, even after inflating a view to it, you can still use methods setPositiveButton and setNegativeButton, they will appear below your inflated layout in the dialog. So, beware inflating buttons AND using those methods, because the buttons will appear duplicated.
Since, in this case, you don't want them to be gray, you want to put buttons inside your layout, with whatever style you want, and inflate them (and reference them in your code through findViewById).
The biggest advantage of the second way is that you can inflate whatever you want, with the styles you want. You can even put images inside it, if you wish.
Hope it helps, let me know if it worked for you.
Context is an interesting topic in android. And one thing to understand is Application Context and Activity Context are different. You should make sure that any thing that is related to UI, you should be using Activity Context.
This can be things like
Showing a dialog
Starting another activity
Inflating a new layout
This is because Activity is the only Context on which the themes defined in your manifest are actually attached.
I also recommend Context, What Context article to get a complete picture.
Happy Coding :)
I am trying to make a spinner I have selectively translate strings on a page. I have my app set up to translate the bulk of the page based on locale languages already. In the image below, The locale language will effect the top string, but I have a spinner on my home page that has all the available android languages in it, and I want users to be able to select one of the spinner items, and as a result the bottom string in the picture below will be translated to that language. I can't find a way to set it up, all the advice I've seen so far is just how to configure the application to set up locale language's. Any direction would be greatly appreciated!
I think you can use Android-LocalizationActivity
Here a portion of its readme:
It's basic for android application to be supported multiple languages. Yeah! It's very easy because android has String Resource. Developer just had to prepare the text for different languages then android system will use itself. But frequently problem is "On-time Language Changing". Because the String Resource was designed to be depending on current device language. but if we want to change the language by click some button. It will be difficult to handle it. This problem will solved because I have created a new library to handle application language. It called "Localization Activity" library.
It's so simple to implement it. Just extend your Activity with LocalizationActivity. Here a sample code with Button:
import android.os.Bundle;
import android.view.View;
import com.akexorcist.localizationactivity.LocalizationActivity;
public class MainActivity extends LocalizationActivity implements View.OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
findViewById(R.id.btn_th).setOnClickListener(this);
findViewById(R.id.btn_en).setOnClickListener(this);
}
#Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_en) {
setLanguage("en");
} else if (id == R.id.btn_th) {
setLanguage("th");
}
}
}
When user click btn_th (Thailand), all language will be translated to Thai language. So you only need to adjust it with spinner.