I'm having a problem with my Android app. It's probably a simple Java problem, but I don't know Java well enough to know what to google. Below is a simplified version of what I have that illustrates my problem. I want to be able to access gridview from my dialog. Clearly what I have here isn't right. I tried moving the declaration outside of the onCreate method, but then my application crashes right at the start (there's no error message). I also tried adding it as an argument to ShowDialog, but I guess since I'm overriding that function that didn't work. As you can probably tell, I don't know what I'm doing. Thoughts?
public class HelloGridView extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
((ImageAdapter) gridview.getAdapter()).initializemThumbIds();
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
showDialog(0);
}
});
}
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
gridview.setAdapter(new ImageAdapter(this)); // gridview cannot be resolved
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
HelloGridView.this.finish();
}
});
AlertDialog diag = builder.create();
return diag;
}
}
I think you just don't have the correct scope, so below I made gridView a member variable. But I think what you really want to do is make your ImageAdapter a member variable and update the ImageAdapter only in your Dialog "yes" click.
public class HelloGridView extends Activity {
private GridView gridview;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
((ImageAdapter) gridview.getAdapter()).initializemThumbIds();
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
showDialog(0);
}
});
}
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
gridview.setAdapter(new ImageAdapter(this)); // gridview cannot be resolved
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
HelloGridView.this.finish();
}
});
AlertDialog diag = builder.create();
return diag;
}
}
Related
I have created a custom dialog showing a grid of items. When another option is clicked, it will also open another custom dialog with an editText field. The problem I am facing is getting a null object error for the textfield. I found an answer here but when I applied it, the result is still the same.
Basically, the app is crashing when retrieving the textfield value in the custom dialog that opens from another custom dialog. Here is what I have so far:
onCreate()
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button donate = findViewById(R.id.button);
donate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDonateDialog();
}
});
}
showDonateDialog()
//Donate dialog with grid options
private void showDonateDialog() {
// Prepare grid view
GridView gridView = new GridView(this);
String[] donateAmount = getResources().getStringArray(R.array.donationAmount);
List<String> donateList = new ArrayList<String>();
Collections.addAll(donateList, donateAmount);
gridView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, donateList));
gridView.setNumColumns(3);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), "Thank you for your donation!", Toast.LENGTH_SHORT).show();
}
});
// Set grid view to alertDialog
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(gridView);
builder.setTitle("Donate");
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setNeutralButton("Other amount", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
showCustomDonate();
}
});
builder.setCancelable(false);
builder.show();
}
showCustomDonate()
//Donate dialog for custom amount
private void showCustomDonate() {
AlertDialog.Builder builderCustom = new AlertDialog.Builder(this);
Context context = builderCustom.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.custom_donate_amount, null, false);
final EditText donateAmount = findViewById(R.id.editAmount);
final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_NEGATIVE) {
dialog.cancel();
} else {
String amount = donateAmount.getText().toString(); //Error null object reference here
Toast.makeText(getApplicationContext(), "Thank you for donating " + amount, Toast.LENGTH_LONG).show();
}
}
};
builderCustom.setView(view)
.setTitle("Custom Donation")
.setCancelable(false)
.setPositiveButton("OK", listener)
.setNegativeButton("CANCEL", listener)
.show();
}
Log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.customdialog, PID: 12011
java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
at com.example.customdialog.MainActivity$5.onClick(MainActivity.java:94)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
i hope it is work for you
showCustomDonate()
//Donate dialog for custom amount
private void showCustomDonate() {
AlertDialog.Builder builderCustom = new AlertDialog.Builder(this);
Context context = builderCustom.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.custom_donate_amount, null, false);
final EditText donateAmount = findViewById(R.id.editAmount);
final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_NEGATIVE) {
dialog.cancel();
} else {
String amount = donateAmount.getText().toString(); //Error null object reference here
Toast.makeText(getApplicationContext(), "Thank you for donating " + amount, Toast.LENGTH_LONG).show();
}
}
};
builderCustom.setView(view)
.setTitle("Custom Donation")
.setCancelable(false)
.setPositiveButton("OK", listener)
.setNegativeButton("CANCEL", listener)
.show();
}
Change on this line
final EditText donateAmount = view.findViewById(R.id.editAmount);
i'm trying to get into MVVM pattern and my problem is that I'm not really sure if I use it correctly. View is responsible for all UI operations (like show stuff?) but what happens when we need to change something in the logic.
So what I really wanna do is, show a dialog with certain options, pick one and reload the app.
I have implement the functions in MainActivity class and i use mCountrySelection.show() when action needed.
public void createCountriesDialog()
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
dialogBuilder.setTitle("Available Countries");
GridView gridView = new GridView(MainActivity.this);
final String[] countries = getResources().getStringArray(R.array.countries);
final String[] codes = getResources().getStringArray(R.array.codes);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, countries);
gridView.setAdapter(arrayAdapter);
dialogBuilder.setView(gridView);
dialogBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
mCountrySelection = dialogBuilder.create();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
fragmentTransaction.commit();
mCountrySelection.dismiss();
}
});
}
public void createAboutDialog()
{
AlertDialog.Builder aboutBuilder = new AlertDialog.Builder(MainActivity.this);
aboutBuilder.setTitle("Top News v1.0");
aboutBuilder.setMessage("Simple application for displaying Top Headlines from newsapi.org.\n\nIcons made by Freepik from www.flaticon.com.");
aboutBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
}
});
mAbout = aboutBuilder.create();
}
Make 1 interface ItemClick and implement this interface from where you are calling Dialog.
public interface ItemClick{
public void onClick(int position, String country);
}
Pass this interface reference to your dialog method
public void createCountriesDialog(ItemClick listner)
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
dialogBuilder.setTitle("Available Countries");
GridView gridView = new GridView(MainActivity.this);
final String[] countries = getResources().getStringArray(R.array.countries);
final String[] codes = getResources().getStringArray(R.array.codes);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, countries);
gridView.setAdapter(arrayAdapter);
dialogBuilder.setView(gridView);
dialogBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
listener = null;
}
});
mCountrySelection = dialogBuilder.create();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
listener.onclick(position, countries[position]);
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
fragmentTransaction.commit();
mCountrySelection.dismiss();
}
});
}
Then when you click on grid item, using interface reference call onclick method
Now when you will receive a callback in onClick(int pos , String country)
Using your view model make api call and reload screen.
Set listener =null when dialog dismiss to avoid memory leaks
1- Expose a mutable LiveData or Observer in your ViewModel
public MutableLiveData<Pair<String, String>> countryInfo = new MutableLiveData<>()
2- Pass the user selection to the ViewModel
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
viewModel.countryInfo.setValue(new Pair(countries[position], codes[position]))
mCountrySelection.dismiss();
}
3- Run your use-case (business logic) in your ViewModel (uploading info to server, saving it in database, etc.)
4- Update View through exposing another Observable (in this case the same countryInfo will work)
In MainActivity observe the countryInfo:
viewmodel.countryInfo.observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable final String newName) {
// Update the UI
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
getSupportFragmentManager().beginTransaction();
.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
.commit();
}
});
P.S: It is considered best if you move this line to ViewModel as it is contain part of business logic:
PreferencesManager.setCountry(countries[position], codes[position]);
My issue issue is this one: When I press long click on item, I have two views which appears.
See below my code for java class. PLease help.
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
Intent intent = new Intent(MyGoodsActivity.this, CurrentActivity.class);
Bundle bundle = new Bundle();
bundle.putLong(Record.BUNDLE_SHOP_ID, mShopId);
bundle.putLong(Record.BUNDLE_the_ID, mGoodsAdapter.getItemId(position));
intent.putExtras(bundle);
MyGoodsActivity.this.startActivity(intent);
}
});
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
AlertDialog.Builder dialog = new AlertDialog.Builder(MyGoodsActivity.this);
dialog.setTitle(R.string.tip);
dialog.setMessage(R.string.info_confirm_delete_this_item);
dialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
MyDB db = new MyDB(MyGoodsActivity.this);
db.deleteGoodsById(mGoodsAdapter.getItemId(position));
refreshListgoods();
}
});
dialog.setNegativeButton(R.string.ko, null);
dialog.show();
return false;
}
}
);
After analyse my code I have juste return true for resolve my issue.
dialog.setNegativeButton(R.string.ko, null);
dialog.show();
return true;
}
I'm making a simple to do list and I want to be able to click on the item and enter a new text which will then replace the text of the TextView in that cell. I've got the dialogAlert working, I just don't know how to grab the cell's TextView and change it
This is what the Activity looks like,
public class MainActivity extends AppCompatActivity {
private ListDataSource ds;
private ListView listViewToDo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context context = this;
Log.d("MainActivity","Attempting to create data source");
try {
ds = new ListDataSource();
}
catch(Exception e)
{
e.printStackTrace();
Log.d("MainActivity","Failed to create data source");
}
Log.d("Main Activity","Attempting to link empty list view to on screen view");
listViewToDo = (ListView)findViewById(R.id.listOfLists);
Log.d("Main Activity","Views linked, Attempting to set adapter to listView");
listViewToDo.setAdapter(new ListDataSourceAdapter(this, ds));
Log.d("Main Activity", "Successfully set Adapter");
// add button listener
listViewToDo.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id)
{
AlertDialog.Builder editItem = new AlertDialog.Builder(context);
final EditText edittext = new EditText(context);
editItem.setTitle("Change Item");
editItem
.setMessage("Set new todo item")
.setView(edittext)
.setCancelable(false)
.setPositiveButton("Submit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
//what do I put here?
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
AlertDialog alertDialog = editItem.create();
alertDialog.show();
}
});
}
}
ds.remove(position);
ds.add(position,edittext.getText().toString().trim())
ListDataSourceAdapter adapter = new ListDataSourceAdapter(this, ds)
listViewToDo.setAdapter(adapter );
adapter.notifDataSetChanged();
In my Android application I created a custom DialogFragment with a custom View but I want the Positive and Negative Button with transparent background.
So I saw some SO answers and i did something like this:
private class PersonalInfoDialogFragment extends DialogFragment {
#Override
public void onStart(){
super.onStart();
Button pButton = ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_POSITIVE);
Button nButton = ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_NEGATIVE);
pButton.setBackgroundColor(getResources().getColor(Color.TRANSPARENT));
nButton.setBackgroundColor(getResources().getColor(Color.TRANSPARENT));
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view=inflater.inflate(R.layout.personalinformation_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.personalinformation)
.setView(view)
.setPositiveButton(R.string.edit, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//Some code
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
final AlertDialog dialog = builder.create();
//I also tried this: dialog.getButton(DialogInterface.BUTTON_POSITIVE).setBackgroundColor(Color.TRANSPARENT);
return dialog;
}
}
I don't get why I am facing NullPointerException. Any idea?
public Button pButton ,nButton ;
#Override
public void onStart(){
super.onStart();
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
final View view=inflater.inflate(R.layout.personalinformation_dialog, null);
pButton = ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_POSITIVE);
nButton = ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_NEGATIVE);
pButton.setBackgroundColor(getResources().getColor(Color.TRANSPARENT));
nButton.setBackgroundColor(getResources().getColor(Color.TRANSPARENT));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.personalinformation)
.setView(view)
.setPositiveButton(R.string.edit, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//Some code
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
final AlertDialog dialog = builder.create();
//I also tried this: dialog.getButton(DialogInterface.BUTTON_POSITIVE).setBackgroundColor(Color.TRANSPARENT);
return dialog;
}
}