Is it possible to display the following data from sqlite database in a listview instead of a toast as shown in the code below ?
btnlist = (Button) findViewById(R.id.btnlist);
btnlist.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
handler = new Datahandler(getBaseContext());
String getName, getaddress, getDate, getTime, getSchoolName;
getName = "";
getaddress = "";
getDate = "";
getTime = "";
getSchoolName = "";
handler.open();
Cursor C = handler.returnData();// return actual data from
// database
if (C.moveToFirst()) {
do {
getName = C.getString(0);
getaddress = C.getString(1);
getDate = C.getString(2);
getTime = C.getString(3);
getSchoolName = C.getString(4);
} while (C.moveToNext());
}
handler.close();
Toast.makeText(
getBaseContext(),
" Name :" + getName + "Address :"
+ getaddress + "Date :" + getDate + "Time :"
+ getTime + "School :" + getSchoolNname,
Toast.LENGTH_LONG).show();
}
});
}
By list view I'm assuming you mean the first row to have the name, second row to have address, third to have date and so forth? If so I would suggest that you actually make 10 textviews, 5 for labels, and 5 for data. You can put them into a scroll view if you need scrolling. Once you have these text views call .setText(...) on the 5 ones with data to populate them with the data you have in the variables such as getName.
The reason I say to do this is to stay more consistent with typical Android design. Typically list views are used to show lists of data where each row shows different values for the same key such as your contacts. It looks like you will always have five data points so we don't need the overhead of a list view and a static set of text views will serve this purpose just fine.
yes of course its possible :)
You've already done the hard work of getting the data out of the database.
I've put together a super quick example for you. Obviously you'll need to fill in the gaps by reading about a bit and following a few tutorials. Here's a good start:
http://www.vogella.com/tutorials/AndroidListView/article.html
http://webdeveloperpadawan.blogspot.co.uk/2014/09/android-listview-with-differing-rows.html
What you need to do is create a custom object for your student details or whatever they are. Then instead of doing
String getName = C.getString(0)
you would do something like this:
List<Student> students;
Student student;
do{
student.setName(C.getString(0));
...
//Then you add that student into a List of students
students.add(student);
}
Then create a custom adapter which extends your list of students:
public class AdapterStudents extends ArrayAdapter<Student>{
//...
}
Then you create an instance of your adapter and finally just set that adapter to your listview.
As I say follow a few tutorials for more specifics but there's your basic plan of action :)
Good luck.
Related
I have a program GUI that the user enters ID#, First Name, Last Name, Salary, Start Date. After the user enters this information into a text area for each information need, the users clicks the add button which stores the information into an arrayList. After clicking add, the user presses a "list" button to output all the information entered into a Panel.
Array list to store users data:
public class EmploymentRecords extends javax.swing.JFrame {
ArrayList <Data> Output = new ArrayList <Data>();
Remove Button code:
private void btnRemoveActionPerformed(java.awt.event.ActionEvent evt) {
int index;
String id = txtID.getText();
boolean idCheck = Output.contains(id);
if (idCheck = true){
index = Output.indexOf(id);
Output.remove(index);
lblError.setText("Employee found and has been removed.");
}
else {
lblError.setText("Employee not found. Please try again.");
}
class Data:
class Data {
String id, firstName, lastName, salary, startDate;
Data (String _id, String _firstName, String _lastName, String _salary, String _startDate) {
id = _id;
firstName = _firstName;
lastName = _lastName;
salary = _salary;
startDate = _startDate;
Heres my problem: I want the user to be able to enter an id in the text area of the GUI where the program checks if that ID is entered before and totally removes all the data from the output screen and arraylist using just the ID. The code I entered above is not working for me and when I press the remove button nothing happens.
Please help as i would appreciate this... Thanks!
You are missing some code to share. But lets suppose your "add" functionality is working.
Lets also suppose that "String id = txtID.getText();" will be able to get the id for you as a string.
An obvious mistake is "if (idCheck = true)", as in java you compare with "=="
So maybe you can try to fix it that way and report the answer.
What you have done works alright for single entity objects within an ArrayList (like ArrayList<String> or ArrayList<Integer> for example) but not so good for multi-entity objects like what you have in your Data class. In other words, each element within your ArrayList is holding an instance of a class and all members related to it, not just a simple String or an Integer.
You will need to go a wee bit deeper in order to actually acquire the ID of any particular Data object instance for comparison to what someone has supplied within a GUI, for example:
private void btnRemoveActionPerformed(java.awt.event.ActionEvent evt) {
String id = txtID.getText();
boolean found = false;
for (Data data : Output) {
if (data.id.equals(id) {
found = true;
Output.remove(data);
clearFieldsInForm();
break;
}
}
if (found) {
lblError.setText("Employee was successfully removed.");
}
else {
lblError.setText("Invalid ID! Employee not found! Please try again.");
}
}
You will notice the clearFieldsInForm(); method use in the above code. This method would just set all pertinent form fields to Null String ("") which is essentially nothing:
private void clearFieldsInForm() {
txtID.setText("");
txtFirstName.setText("");
txtLastName.setText("");
txtsalary.setText("");
txtStartDate.setText("");
}
When I attempt to read from SQLite and use adapter.NotifyDataSetChanged. I don't see any changes in my recyclerView.
The main idea is to search in SQLite where the name contains a value from a textView.
Then to repopulate again my adapter.
I create an Instance
private List<InventoryPreviewClass> mItems;
private RecyclerView mRecyclerView;
adpInventoryPreview adapter;
Then inside onCreate() method
mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where CategoryID =" + CategoryID + ""); //Here i am reading from sqlite
mRecyclerView.HasFixedSize = true;
var layout = new GridLayoutManager(this, InventoryRowsPerLine, GridLayoutManager.Vertical, false);
mRecyclerView.SetLayoutManager(layout);
adapter = new adpInventoryPreview(mItems);
mRecyclerView.SetAdapter(adapter);
Until now the code works.
My recyclerView is populated with my items from sqlite.
Here is the method when a user types something in TextView
private void EtSearchAlwaysOn_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
{
mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
adapter.NotifyDataSetChanged();
}
When I am typing something nothing changes in my recyclerView.
Why is this happening?
The only way I found that this works is to reset my items inside my adapter for example:
mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
adapter = new adpInventoryPreview(mItems);
mRecyclerView.SetAdapter(adapter);
Why is this happening? I don't think that the second method is right.
This is happening because you are assigning a new object to mItems
The first time you create the mItems list, you pass it onto your adapter, when the next time you are getting a response from your SQLite DB is creating a new instance of the list since you are assigning it to the object.
What you need to do is
Create a method in the adapter that accepts your items like adapter.updateItems(newItems)
The method should clear the list like items.clear() and then add the new items you passed it with items.addAll(newItems)
After that you can call notifyDataSetChanged() within the adapter itself and it will work.
In your, adapter it will look like this
public void updateItems(final List<InventoryPreviewClass> newItems) {
items.clear();
items.addAll(newItems);
notifyDataSetChanged();
}
and then you can call it like this
updatedList = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where CategoryID =" + CategoryID + "");
adapter.updateItems(updatedList);
I think you missed the point that this is the typical case of pass by value and not pass by reference.
This is a byRef issue.
You pass memory pointer 1 to your adapter and tell it to monitor for changes.
Then you load a list and repoint your memory pointer to spot 2.
Then you tell adapter that it's monitored memory at pointer 1 has changed.
You have two options.
Modify the original list by comparing new results with old results, removing and adding as necessary
or Tell the adapter it has a new memory pointer that it is monitoring by changing the items inside the adapter. Making a method for swapItems(items) will work. Then call notifyDataSetChanged inside the adapter.
you have to set items in your adapter,
create a setter like this :
private List<InventoryPreviewClass> mItems;
.
.
.
public void setItems(List<InventoryPreviewClass> items)
{
mItems=items;
}
and then update your search method like this
private void EtSearchAlwaysOn_TextChanged(object sender,
Android.Text.TextChangedEventArgs e)
{
mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass
where InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
adapter.setItems(mItems);
adapter.NotifyDataSetChanged();
}
Notify adapter after you set adapter.
mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
adapter = new adpInventoryPreview(mItems);
mRecyclerView.SetAdapter(adapter);
adapter.notifyDataSetChanged();
after taking a look at the app by google called google keep, I was immediately curious on how exactly does the search of the app works.
Here is the image of the app:
Whenever you search something, the card that doesn't match would disappear. How exactly do they achieve this because I think that the card are basically custom views and the layout is a custom layout. My problem is that I don't know how to implements a search for custom view.
Note: I have taken a look at some internet example online for search view and I can only find the implementation of searches for listview which is not precisely what I want.
I had a similar problem, so I made my Custom views properties (e.g. name, tag, id, etc...) into a single String spaced by a single space " ".
Something like this inside my CustomView class:
public String toString() {
return (this.name + " " + this.tag + " " + this.coords + " " + this.id );
}
And then I filtered my Custom views through all current Custom views that were shown:
ArrayList<CustomView> filteredList = new ArrayList<>();
...
private void filter(String constraint) {
for(CustomView view : AllViews) {
if (!filteredList.contains(view))
if (view.toString().toLowerCase().contains(constraint.toLowerCase())) {
filteredList.add(view);
break;
}
}
}
// Do something to add the filteredList to your adapter
// and show the new list of CustomViews.
}
You can call filter(newText) method inside onQueryTextChange(String newText) from SearchView OnQueryTextListener().
This way, if whatever word you type in the SearchView is found anywhere in any CustomView, the correspondent CustomView will be visible, otherwise the view will "disappear".
Hope this helps.
private int info = 1;
public void nextStep(View view)
{
TextView textInfo = (TextView) findViewById(R.id.textInfo);
textInfo.setText(R.string.info1);
info++;
}
When one button is clicked, method nextStep is called. And every time a button clicked, I want to show different info, first time it's info1 string, next time it's info2 string and etc. from strings.xml. I would like to do something like that:
private int info = 1;
public void nextStep(View view)
{
TextView textInfo = (TextView) findViewById(R.id.textInfo);
textInfo.setText(R.string.info + info);
info++;
}
Of course, it's not possible. What should I do? I really don't want to write a big if/else or switch statement. Thanks.
Of course, it's not possible.
Actually, it is. You can use getIdentifier to do this:
private int info = 1;
public void nextStep(View view)
{
TextView textInfo = (TextView) findViewById(R.id.textInfo);
int myStrId = textInfo.getContext().getResources().getIdentifier("info"+info, "string", textInfo.getContext().getPackageName());
textInfo.setText(myStrId);
info++;
}
getIdentifer() is a way to fetch resource IDs that are stored in R if you don't know the exact name. While it isn't the most efficient method in the world, it suffices in situations where referencing R (such as your situation) is not possible.
The method returns the same ID that R would; that is, getIdentifier("info1", "id", ...); is the same as R.id.info1, since R is just a compiled version of it. This method also works in the event that you are unsure if an ID exists (such as from an external library) but need to reference it anyway.
Use an array of String or better a List<String> such as an ArrayList<String> and fill it with the Strings from the XML. Then you can use the get(int index) method to get the ith String in the list.
If you are using JAXB to unmarshall your XML, you can have it set up to create your List for you without much fuss.
I have a ListAdapter which takes the dates from my SQLite database and displays them all on the list. The thing is, the date is not in human readable format, and I have a helper method to perform the conversion, but how do I implement it on my code?
This is how my code looks like:
// Get all of the notes from the database and create the item list
Cursor c = mDbHelper.fetchAllItems();
startManagingCursor(c);
String[] from = new String[] { TrackerDbAdapter.KEY_DATE };
int[] to = new int[] { R.id.row_date };
// Now create an array adapter and set it to display using our row
SimpleCursorAdapter history =
new SimpleCursorAdapter(this, R.layout.history_row, c, from, to);
setListAdapter(history);
I would try creating a custom ListAdapter or custom SimpleCursorAdapter
If you do not need to use a cursor, have a look at this link. http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/ It explains how to use an arraylist and custom listAdpater.
You can also do the same with the SimpleCursorAdapter. I was unable to find a good tutorial at this time. I will add to this when I do
Use SimpleCursorAdapter.ViewBinder to attach the formatted data to Views.
SimpleCursorAdapter.ViewBinder dataBinder = new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
((TextView)view).setText(cursor.getString(columnIndex));
return true;
}
};
simpleCursorAdapter.setViewBinder(dataBinder)
Option 1: Like #nguyendat said, for performance, you could store the formatted date in the database, as well as the un-formatted version, to give you the most flexibility. If in the same table though, this would violate 2nd normal form because of the redundancy, and you would have to be careful in your code to update all of the data in the row.
To implement this, put your conversion code in your DBAdapter, in the insert command.
Option 2: Create a class for your date
public class FormattedDate {
private int oneDate;
public Punch (int unformattedDate) {
oneDate = unformattedDate;
} // ends constructor
#Override
public String toString() {
//put your conversion code here
return myFormattedDate;
}}
This has the added benefit of a proper place to put any other code for comparisons or conversions.
Inside your DBAdapter, change your query to this
public ArrayList<FormattedDate> fetchAllItems() {
ArrayList<FormattedDate> results = new ArrayList<FormattedDate>();
Cursor c = db.rawQuery("SELECT MY_UNFORMATTED_DATE FROM yourTable", null);
if (c.getCount() > 0) {
c.moveToFirst();
do {
results.add( new FormattedDate(c.getInt(c.getColumnIndex(MY_UNFORMATTED_DATE))));
} while (c.moveToNext());
}
c.close();
return results;
}
This returns an ArrayList of FormattedDate objects
Finally, this would populate a listview
setContentView(R.layout.my_list_view);
ArrayList<FormattedDate> dateArray = mDBHelper.fetchAllItens();
ArrayAdapter<FormattedDate> dateAdapter = new ArrayAdapter<FormattedDate> (getApplicationContext(), R.layout.list_item, dateArray);
setListAdapter(dateAdapter);