I have created a screen with 5 rows of information. each row has 2 values. (value1 and value2)
At the end of each row is a button. For each row I have created a xml file that I am looping though and filling in the values from a database
what I am looking at doing is when the button is pressed a dialog is opened with two editviews filled in with the values from that row
Then when the button is pressed on the dialog the values are updated in database.
I am having problems with the createdialog / preparedialog methods and passing the values to them.
UPDATE with Code
public void createLayout(LinearLayout pMainlayout, String pMajorValue) {
DatabaseTools db = new DatabaseTools(this);
majorValue= pMajorValue;
nameInfo = db.getNames(pMajorValue);
name = returnName(pMajorValue);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < nameInfo.size(); i++) {
// Get views
View view = (View) inflater.inflate(R.layout.mainlayout, null);
TextView nameView = (TextView) sightmarkView.findViewById(R.id.name_title);
TextView Value1View = (TextView) sightmarkView.findViewById(R.id.value1);
TextView ValueView = (TextView) sightmarkView.findViewById(R.id.value2);
Button updateButton = (Button) sightmarkView.findViewById(R.id.updatebutton);
// Get info from Database
nameValue = nameInfo.get(i).toString();
value1v = db.getMark(majorValue, nameInfo.get(i).toString());
value2v = db.getMark(majorValue, nameInfo.get(i).toString());
// populate info into fields
nameView.setText(nameValue);
Value1View.setText(String.valueOf(value1));
Value2View.setText(String.valueOf(value2));
updateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Bundle bundle = new Bundle();
//Code here to add values to a bundle
showDialog(SIGHTMARK_DIALOG_ID, bundle);
}
});
pMainlayout.addView(view);
}
}
All this work correctly. The values are displayed. I have looked into using a bundle to pass them into the dialog
#Override
protected Dialog onCreateDialog(int id, Bundle bundle) {
switch(id) {
case DIALOG_ID:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View layout = inflater.inflate(R.layout.update, (ViewGroup) findViewById(R.id.update));
final EditText value1Edit = (EditText) layout.findViewById(R.id.value1_current);
final EditText value2Edit = (EditText) layout.findViewById(R.id.value2_current);
//next pull values from bundle to populate into fields
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
// Now configure the AlertDialog
builder.setTitle(R.string.sight_update_title);
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
this.removeDialog(DIALOG_ID);
}
});
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
value1New = Float.parseFloat(value1Edit.getText().toString());
value2New = Float.parseFloat(value2Edit.getText().toString());
// method run to update the database with the new values passed to it
updateMarks(value1, value2);
this.removeDialog(DIALOG_ID);
}
});
// Create the AlertDialog and return it
AlertDialog Dialog = builder.create();
return Dialog;
}
return null;
}
This part has issues and is not getting the values correctly or passing them to the update method
i think the problem is here:
If you use showDialog(int), the activity will call through to this
method the first time, and hang onto it thereafter. Any dialog that is
created by this method will automatically be saved and restored for
you, including whether it is showing.
remove references
removeDialog(SIGHTMARK_DIALOG_ID);
showDialog(SIGHTMARK_DIALOG_ID, bundle);
documentation
Related
I'm building an app that is supposed to take text entered from the user and place them into the textviews in a custom list item. The user enters the text into an AlertDialog but once the AlertDialog closes (hence destroyed), all the text entered is destroyed alongside with it and gives me a NullPointerException error.
This is code that handles the Dialog creation and data retrieving:
public class AssignmentActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_assignment);
...
FloatingActionButton assignmentAddButton = (FloatingActionButton) findViewById(R.id.assignment_add_button);
assignmentAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editCourseInfoDialog();
}
});
}
private void editCourseInfoDialog() {
LayoutInflater inflater = LayoutInflater.from(AssignmentActivity.this);
View dialogLayout = inflater.inflate(R.layout.assignment_edit_dialog, null);
AlertDialog.Builder dialog = new AlertDialog.Builder(AssignmentActivity.this);
dialog.setView(dialogLayout);
final TextView name = (TextView) dialogLayout.findViewById(R.id.assignmentNameView);
final TextView mark = (TextView) dialogLayout.findViewById(R.id.assignmentMarkView);
final TextView overallMark = (TextView) dialogLayout.findViewById(R.id.assignmentOverallMarkView);
final TextView weight = (TextView) dialogLayout.findViewById(R.id.assignmentWeightView);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
assignment.setName(String.valueOf(name.getText()));
assignment.setMark(Double.valueOf(mark.getText() + ""));
assignment.setMarkOutOf(Double.valueOf(overallMark.getText() + ""));
assignment.setPercentage(Double.valueOf(weight.getText() + ""));
assignmentAdapter.notifyDataSetChanged();
dialog.dismiss();
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
}
The issue with your initialization.
LayoutInflater inflater = LayoutInflater.from(AssignmentActivity.this);
View dialogLayout = inflater.inflate(R.layout.assignment_edit_dialog, null);
AlertDialog.Builder dialog = new AlertDialog.Builder(AssignmentActivity.this);
dialog.setView(dialogLayout);
final TextView name = (TextView) dialogLayout .findViewById(R.id.assignmentNameView);
final TextView mark = (TextView) dialogLayout .findViewById(R.id.assignmentMarkView);
final TextView overallMark = (TextView) dialogLayout .findViewById(R.id.assignmentOverallMarkView);
final TextView weight = (TextView) dialogLayout .findViewById(R.id.assignmentWeightView);
As you said TextViews are hooked up with AlertDialog custom view then they view context should be of Dialog view.
You have a lot to learn in terms of concept. You are setting adapter before initializing your list.
assignmentAdapter = new AssignmentListAdapter(assignmentList, this); // at this line **assignmentList** is null as you initiliaze after this line
assignment = new Assignment(this);
You must initialize first like this
assignment = new Assignment(this);
assignmentAdapter = new AssignmentListAdapter(assignmentList, this);
I have the following AlertDialog and its onClick method:
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setView(View.inflate(this, R.layout.barcode_alert, null));
alertDialog.setPositiveButton("Search", new DialogInterface.OnClickListener() {
#Override
public void onClick(#NotNull DialogInterface dialog, int which) {
// how to get editTextField.getText().toString(); ??
dialog.dismiss();
}
});
The XML I inflate in the dialog (barcode_alert.xml) contains, among other things, an EditText field, and I need to get its string value after the user taps the Search button.
My question is, how do I get a reference to that field so I can get its text string?
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
final View v = View.inflate(this, R.layout.barcode_alert, null); //here
alertDialog.setView(v);
alertDialog.setPositiveButton("Search", new DialogInterface.OnClickListener() {
#Override
public void onClick(#NotNull DialogInterface dialog, int which) {
((EditText)v.findViewById(R.id.edit_text)).getText().toString(); //and here
dialog.dismiss();
}
});
Try this,
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
final View v = getLayoutInflater().inflate(this, R.layout.barcode_alert, null);
final EditText editTextField = (EditText) v.findViewById(R.id.edit_text);
editTextField.setOnClickListener(MyActivity.this);
alertDialog.setView(v);
alertDialog.setPositiveButton("Search", new DialogInterface.OnClickListener() {
#Override
public void onClick(#NotNull DialogInterface dialog, int which) {
String enteredValue = editTextField.getText().toString(); // get the text from edit text
dialog.dismiss();
}
});
You can inflate your view and get a reference to a variable:
View v = View.inflate(this, R.layout.barcode_alert, null);
you can use findViewById to get a reference to your view. Make sure that your variable is final or a member variable. Otherwise you cannot access it in the onClickListener
final EditText editText = (EditText)v.findViewById(R.id.your_edit_text
I created an 2 activities, Home and timetable. In the home activity, i have a button which opens the timetable page. When the user clicks on the button, the timetable activity opens. In the OnCreate method of timetable activity, i have an AlertDialog which is used to collect a number (I know i can use a Number Picker here, but i prefer this).
Here is my timetable Activity Code:
private View view;
private int maxLength = 2;
TableLayout table;
private int testint;
LayoutInflater getLayoutInflater;
Inflater inflater;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.activity_time_table, null);
// Alert Dialog for Collecting Number of Courses Offered
setNumberOfCourses();
ViewGroup root2 = (ViewGroup) root.findViewById(R.id.TimeTableSetter);
for (int i=0; i<testint; i++){
view = getLayoutInflater(savedInstanceState).inflate(R.layout.timetablerowitem, root2, false);
root2.addView(view);
}
return root;
}
private void setNumberOfCourses() {
AlertDialog.Builder setNum = new AlertDialog.Builder(getActivity());
setNum.setTitle ("Number of Courses");
setNum.setMessage("How Many Courses do you offer");
final EditText CourseNos = new EditText(getActivity());
CourseNos.setInputType(InputType.TYPE_CLASS_NUMBER);
CourseNos.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength )});
setNum.setView(CourseNos);
setNum.setPositiveButton("Ok", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int goBtn) {
// TODO Auto-generated method stub
String CourseValue = CourseNos.getText().toString();
testint = Integer.parseInt(CourseValue);
}
});
setNum.setNegativeButton("Back", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int bkbtn) {
// TODO Auto-generated method stub
Intent backHome = new Intent(getActivity(), Jack_heart.class );
startActivity(backHome);
}
});
setNum.show();
}
--- In this activity, i am creating a certain number of rows based on the value entered by the user in the alertDialog.
Everything works fine, as a matter of fact if i replaced the testint in the for statement with an integer lets say 4, four timetablerows are created. But when i use testint, and i insert a value in the edit text field, nothing happens.
I dont know what the problem is.
Problem in your for-loop is called at time of createView.
Move your for-loop code outside of create view to a seperate method
public void updateTable(){
//you might need to remove existing childs before updating table
ViewGroup root2 = (ViewGroup) root.findViewById(R.id.TimeTableSetter);
for (int i=0; i<testint; i++){
view = mInflater.inflate(R.layout.timetablerowitem, root2, false);
root2.addView(view);
}
}
Now call this table from your onClick method when you have a new testInt -
setNum.setPositiveButton("Ok", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int goBtn) {
// TODO Auto-generated method stub
String CourseValue = CourseNos.getText().toString();
testint = Integer.parseInt(CourseValue);
updateTable();
}
});
this may help you. add this in xml file in editText box
android:inputType="number"
this intakes only numbers instead of any charecters..
I have a custom SimpleCursorAdapter and a list view. Each row of the list have a name and a button. When I press the button for each name, a dialog appears with a description.
Inside the custom SimpleCursorAdapter I set the onclick method for the button. When I have a large list, my listView gets a scroll bar. And I dont know why, when I scroll down, the last rows of my list doesnt show the correct description for each row. This is my code:
public class listServicesCursorAdapter extends SimpleCursorAdapter{
private Context context;
private int layout;
private String[] from;
private int[] to;
public listServicesCursorAdapter (Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
this.layout = layout;
this.from = from;
this.to = to;
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
//Column of BD that we want to recover
String column = null;
//Index of the column of DB
int nameCol = 0;
//Result of obtain the index of the column of DB
String nombre = null;
//Name of the textView in the Layout where we want to show the result
TextView name_text= null;
String description = null;
String nameService = null;
//For each value of DB, we show it in the text view.
for (int i=0; i<from.length; i++){
column= from[i];
nameCol = cursor.getColumnIndex(column);
name = cursor.getString(nameCol);
//the values to[i] equals to 0 indicates values that we need but
//that we are not showing in the list directly
//0 -> description
if(to[i] == 0){
description = name;
}else{
nameService = name;
name_text = (TextView) v.findViewById(to[i]);
if (name_text != null) {
name_text.setText(name);
}
}
}
ImageButton buttonDescription = (ImageButton) v.findViewById(R.id.imageButtonDescription);
//we store in a bundle the name and description of the service, so we can use it in
// the setOnClickListener method.
final Bundle mArguments = new Bundle();
mArguments.putString("name", nameService);
mArguments.putString("description", description);
buttonDescription .setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setMessage(mArguments.getString("description"))
.setTitle(mArguments.getString("name"))
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}});
return v;
}
}
This is where I call the adapter:
ServiceSqliteDao serviceDao = new ServiceSqliteDao();
//get the services for DB
Cursor mCursorServices = serviceDao.listServices(getActivity());
if(mCursorServices.getCount()>0){
//indicate the fields we want to show (from) and where (to)
String[] from = new String[] { "name", "description"};
int[] to = new int[] { R.id.checkBoxService,0};
ListView lvServices = (ListView) v.findViewById (R.id.listViewServices);
ListServicesCursorAdapter notes = new ListServicesCursorAdapter (getActivity(), R.layout.activity_file_service, mCursorServices, from, to, 0);
lvServices.setAdapter(notes);
Why do I get this behavior?. I get all the names in the list right but when I press the button in horizontal way (I mean a put the tablet horizontally) and get the scroll bar in my list, I dont get the right description. By the other hand, if I use the tablet vertically, I dont get the scroll bar in my list and I get the right description in each button.
This is my layout:
<ListView
android:id="#+id/listViewServices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ListView>
SOLUTION:
newView should look like this:
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
return v;
}
and bindView should look like this:
#Override
public View bindView(View v, Context context, Cursor cursor) {
//Column of BD that we want to recover
String column = null;
//Index of the column of DB
int nameCol = 0;
//Result of obtain the index of the column of DB
String nombre = null;
//Name of the textView in the Layout where we want to show the result
TextView name_text= null;
String description = null;
String nameService = null;
//For each value of DB, we show it in the text view.
for (int i=0; i<from.length; i++){
column= from[i];
nameCol = cursor.getColumnIndex(column);
name = cursor.getString(nameCol);
//the values to[i] equals to 0 indicates values that we need but
//that we are not showing in the list directly
//0 -> description
if(to[i] == 0){
description = name;
}else{
nameService = name;
name_text = (TextView) v.findViewById(to[i]);
if (name_text != null) {
name_text.setText(name);
}
}
}
/********************************NEW CODE ************************************/
String uniMedition = cursor.getString(cursor.getColumnIndex("unitMedition"));
if(uniMedition.equals("none")){
EditText etMedida = (EditText) v.findViewById(R.id.editTextMedida);
etMedida.setVisibility(View.INVISIBLE);
TextView tvUniMedition = (TextView) v.findViewById(R.id.textViewUniMedition);
tvUniMedition .setVisibility(View.INVISIBLE);
}else{
EditText etMedida = (EditText) v.findViewById(R.id.editTextMedida);
etMedida.setVisibility(View.VISIBLE);
TextView tvUniMedition = (TextView) v.findViewById(R.id.textViewUniMedition);
tvUniMedition .setVisibility(View.VISIBLE);
tvUniMedition .setText(uniMedition);
}
/********************************END NEW CODE ************************************/
ImageButton buttonDescription = (ImageButton) v.findViewById(R.id.imageButtonDescription);
//we store in a bundle the name and description of the service, so we can use it in
// the setOnClickListener method.
final Bundle mArguments = new Bundle();
mArguments.putString("name", nameService);
mArguments.putString("description", description);
buttonDescription .setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setMessage(mArguments.getString("description"))
.setTitle(mArguments.getString("name"))
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}});
}
}
Now everything works fine!.
Why do I get this behavior?. I get all the names in the list right but
when I press the button in horizontal way (I mean a put the tablet
horizontally) and get the scroll bar in my list, I dont get the right
description.
When your ListView doesn't have space to show all of the rows it will recycle the row view for performance reasons. The problem is that in your SimpleCursorAdapter you override the newView() method which will be called only when the ListView doesn't have a recycled view. Override bindView() to do the work as that method is called for each row, in the newView() method just inflate/build the row layout.
I have my ListActivity that when you tap on an item, it pops up a Dialog that ask the user for user and password. How can I get the selected position from the dialog?
Here's how I initialize the ListActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = getListView();
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
showDialog(DIALOG_USER_PASSWORD);
}
});
}
The Dialog I pop up is a simple AlertDialog with 2 EditText which I inflate from an xml file
protected Dialog onCreateDialog(int id) {
switch (id) {
...
case DIALOG_USER_PASSWORD:
LayoutInflater factory = LayoutInflater.from(this);
final View dialogView = factory.inflate(R.layout.alert_dialog_text_entry, null);
return new AlertDialog.Builder(MyListActivity.this)
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(R.string.ask_user_password)
.setView(dialogView)
.setPositiveButton(R.string.ok_text, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String userName = ((EditText) findViewById(R.id.username_edit_alert_dialog))
.getText().toString();
String password = ((EditText) findViewById(R.id.password_edit_alert_dialog))
.getText().toString();
Credentials cred = new CredentialsL1(userName, password);
/* HERE IS WHERE i NEED THE SELECTED ITEM
mId IS THE OBJECT ASSOCIATED TO THE SELECTED POSITION */
mService.connect(mId, cred);
}
})
// Cancel button
.setNegativeButton(R.string.cancel_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
})
.create();
}
return null;
}
The only I've come up with is creating a new field "mId" and setting it when the user taps and using it when the user taps OK in the Dialog. Any more elegant idea?
Thanks
private int selectedPosition;
...
protected void onCreate(Bundle savedInstanceState) {
....
// inside the item listener...
selectedPosition = position;
showDialog(DIALOG_USER_PASSWORD);
/* HERE IS WHERE i NEED THE SELECTED ITEM
mId IS THE OBJECT ASSOCIATED TO THE SELECTED POSITION */
// just use selectedPosition var
Any more elegant idea?
It seems that you use a normal ListView (not a checkbox one)... so, it's fine to do it this way.