I have created a database app, where the user can search for a film. The app will then return the results of this search in a ScrollView. I then want these search results to be clickable, which will lead to another page to display full details of the film selected. What is the best way to do this?
public void search(View v){
EditText search = (EditText)findViewById(R.id.edtSearch);
String searchresult = "%" + search.getText().toString() + "%";
db = new DbHelper(this).getReadableDatabase();
String[] tblColumns = {"*"};
String where = "film LIKE ? OR actor LIKE ? OR actor2 LIKE ? OR director LIKE ?";
String[] args = {searchresult, searchresult, searchresult, searchresult};
Cursor results = db.query("FILMTABLE", tblColumns, where, args, null, null, null);
film(results);
}
public void film (Cursor c){
c.moveToFirst();
int titleIndex = c.getColumnIndex("film");
int idIndex = c.getColumnIndex("id");
String title = c.getString(titleIndex);
int filmID = c.getInt(idIndex);
TextView txt = new TextView(getApplicationContext());
txt.setId(filmID);
txt.setText(title);
txt.setTextColor(Color.BLACK);
txt.setTextSize(15);
ScrollView scrollView = (ScrollView)findViewById(R.id.scrolLView);
scrollView.addView(txt);
}
Filter your search result in arraylist and use the listview for showing the result. Then implement listview.setOnItemClickListner.
Follow this : http://www.javacodegeeks.com/2013/06/android-listview-tutorial-and-basic-example.html
Every widget in Android is a clickable object. You can format the results however you like, likely in a ListView and set each one's onClick attribute to be whatever function in Java you need executed when clicked. If they all operate the same, you can just put a click listener on the entire list. If they are intended to operate differently (the more likely case) you can individually assign methods to each element in the list using the above.
Related
I have a Room Database table with multiple columns (PartsTable). I need to fetch only one column from the table that contains one word String and I'm using a subset of a table as per google docs (PartsTuple).
Now I need to create a function that will or something else that will return the ArrayList of fetched data, which I can access in my adapter class. I am able to return the data and see it in a console log (from the main fragment where I get data from ViewModel), but I just can't seem to make it work on a function that will return the said list of data which I could then access from a different class.
Code from DAO:
#Query("SELECT keyword FROM partsTable")
LiveData<List<PartsTuple>> getTuple();
Code from repo:
public LiveData<List<PartsTuple>> getPartsTuple() {
return partsKeyword;
}
Code from view model:
public LiveData<List<PartsTuple>> getPartsTuple() {
return partsKeyword;
}
Fragment class where I display data in a log:
mViewModel.getPartsTuple().observe(getViewLifecycleOwner(), new Observer<List<PartsTuple>>() {
#Override
public void onChanged(List<PartsTuple> partTuple) {
Log.d(TAG, "vraceno: " + partTuple.toString());
}
});
, and data from the log
D/PartsFragment: vraceno: [part1, parts3, part_2]
Code from adapter class where I compare strings and highlight them.
ArrayTEST arrayTEST = new ArrayTEST();
ArrayList<String> values = arrayTEST.getWordFromHardcodedList();
String text = note.getPartsSubtitle();
Spannable textSpannable = new SpannableString(text);
for (int j = 0; j < values.size(); j++) {
//word of list
String word = String.valueOf(values.get(j));
//find index of words
for (int i = -1; (i = text.indexOf(word, i + 1)) != -1; i++) {
//find the length of word for set color
int last = i + word.length();
textSpannable.setSpan(new BackgroundColorSpan(Color.parseColor("#1a0cab8f")),
i, last, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textSpannable.setSpan(new ForegroundColorSpan(Color.RED),
i, last, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
if (note.getPartsSubtitle().trim().isEmpty()) {
tvTEXT.setVisibility(View.GONE);
} else {
tvTEXT.setText(textSpannable);
}
The part that I'm having trouble with is this, where I need to get a list of data from database and not hardCoded like this
arrayTEST.getWordFromHardcodedList();
Now I need to access this list of data from my adapter class since if there is a match I wanna highlight the parts from the list of parts in my main recycler view where all the data is shown. I can do this when I type the list manually but it needs to be dynamic based on user input.
Thanks in advance
In your adapter class add a field for this list - I'll call it highlightedParts. Observe getPartsTuple() as you do, and set the data you get to highlightedParts. Then you need to create a custom setter for highlightedParts and every time it gets called, update elements of the RecyclerView to highlight the desired items. For updating, you can use notifyDataSetChanged() method. There are other, more optimized variations for only updating a specific item or item range, but you're going to have to update entire dataset.
Ended up using shared preferences with Gson.
In app gradle add
implementation 'com.google.code.gson:gson:2.8.6'
Save the data to SP in a fragment:
SharedPreferences sharedPreferences = requireActivity().getSharedPreferences("shared_preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String json = gson.toJson(myListOfData);
editor.putString("partsKEY", json);
editor.apply();
Load the array in the adapter class:
SharedPreferences sharedPreferences = context.getSharedPreferences("shared_preferences", MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPreferences.getString("partsKEY", null);
Type type = new TypeToken<ArrayList<NoteTupleTest>>() {
}.getType();
partsArrayList= gson.fromJson(json, type);
if (partsArrayList== null) {
partsArrayList= new ArrayList<>();
}
I want to populate a listview from an ArrayList received from another activity, but I don't know how to show only the name of the country.
This is what I have tried. This will only show the address of my countries, not the name.
lv = (ListView) findViewById(R.id.listViewCountries);
lv.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, countries));
I expect to have a listView full of only the names of the countries and when I press on one of them to have an activity open to show info about that country.
You could create another array, like :
Arraylist <String> array2 = new ArrayList() ;
for (Country country : countries){
array2.add(country.getname())}
And then in your spinner you put array2 instead of countries.
Since you added them in the same order, their index will be the same than in your countries array, then if you want to get à country back, in your onselected item listener, for example, you just have to out sthg like
Country selectedcountry = countries.get(position);
This is how I did it for a list of contacts :
String [] contractList = new String[user.getUserContractsList().size()];
for (int i = 0; i < user.getUserContractsList().size(); i ++){
contractList[i] = user.getUserContractsList().get(i).getCONTRACT_NAME();
}
//Setting the spinner
ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, contractList);
spin.setAdapter(adapter);
spin.setOnItemSelectedListener(this);
And then to get back the contact value when the user selects an item :
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
contract = user.getUserContractsList().get(position);
}
I don't know if this is clear to you ?
Because you are using default implementatino, such as FragmentList, you have prebuilt xml for item list and hence, cannot change it in right way. You need to implement you custom implementation, with new RecyclerView.
Please search for the information, before asking this question. Basic sample you can find in another answer.
Hi I had asked before how do I update listview and got suggestion to make use of ArrayAdapter.I follow the thing now the issue is about it's updating listviews but not with expected values some object .
My code is like this:
Cursor cursor = db.rawQuery("SELECT count(*) FROM BOOKMARKS ", null);
//if any contact found moveToFirst of that contacts or points to 1st email
cursor.moveToFirst();
//checking columns exhist or not
if (cursor.getInt(0) > 0)
{
//get all the contacts from table 'BOOKMARKS'
c = db.rawQuery("SELECT * FROM BOOKMARKS", null);
//get the index of mentiond and required columns
ID = c.getColumnIndex("ID");
booktitl = c.getColumnIndex("Booktiltle");
audiotime=c.getColumnIndex("BookmarkTime");
// Check result.
c.moveToFirst();
if (c != null)
{
// Loop through all Results
do
{
cont = new String[3];
cont[0] = Integer.toString(c.getInt(ID));
cont[1] = c.getString(booktitl);
cont[2] = c.getString(audiotime);
audiobooks.add(cont);
}
while(c.moveToNext());
c.close();
db.close();//close db resources
ArrayAdapter<String[]> arrayAdapter1=new ArrayAdapter<String[]>(this, R.layout.row3, R.id.itemr1,audiobooks);
lv.setAdapter(arrayAdapter1);
How do i get the string value on listview?Actually the values fetching from database and storing into Arraylist.At present I am displaying some object value on listview but I want to display content that "audiobooks" holds. Please help me to solve it.
You can't give the ArrayAdapter the type String[], because you're giving it a List called audiobooks.
Also, I'm not sure if the standard ArrayAdapter can handle a datatype List<String[]>. It might not work. You would have to make your own implementation of the ArrayAdapter by extending it, if it shouldn't work.
If I understand correctly, you want to populate a ListView with data from each row from your database. You must create a new class of type Audiobook with the member variables corresponding with database row. Then create a layout in your res/layouts folder that must show your object's data. Create a new class extending ArrayAdapter class, in which you inflate views with created layout and populate listview with childs. Then in your main you set the new adapter to the list.
The ArrayAdapter should look like this:
public class AudiobookAdapter extends ArrayAdapter<Audiobook> {
// constructor
// here you populate each view and put it in listview
public View getView (int position, View convertView, ViewGroup parent)
{
}
}
This is a start line, you should read more about extending arrayadapters and custom ListViews.
I've got an array coming in from a cursor in a function from a sqlite database. I'd like to add multiple items to the array to make it easier to bring data in from other pages. I.e. I'd like to do mArray("ID"), mArray("Name") (i'll be populating a listview from an array of the function, and would like to have easy access to name from ID)
Here is my code at the moment which only saves the ID in the array:
public static Array GetRooms(String StationID) {
File dbfile = new File(Global.currentDBfull);
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
Cursor c = db.rawQuery("select * from StationObjects where ObjectID = 0 and StationID = " + StationID , null);
c.moveToFirst();
Log.e("TomDebug", c.getString(c.getColumnIndex("SubGroupName")));
ArrayList<String> mArrayList = new ArrayList<String>();
c.moveToFirst();
while(!c.isAfterLast()) {
mArrayList.add(c.getString(c.getColumnIndex("SubGroupName")));
c.moveToNext();
}
return null;
}
Edit: To give a bit of clarity;
In psudocode i'd like to be able to do:
while(!c.isAfterLast()) {
mArrayList.name.add(c.getString(c.getColumnIndex("Name")));
mArrayList.type.add(c.getString(c.getColumnIndex("Type")));
mArrayList.ID.add(c.getString(c.getColumnIndex("ID")));
c.moveToNext();
}
So that anywhere in the code i can do
Array curRooms = GetRooms("1234")
String name = curRooms.Name
String type = curRooms.Type
(i know the mix between array and string wont work there, but just an example)
It sounds like you want an actual data structure instead of a string. There are a few ways of doing this, with ORMs and whatnot, but a basic example would be something like this, that you can fill the fields in from the database.
public class StationObject
{
public String name;
public String type;
public String id;
}
//pseudocode
for each result in resultset
fill temp StationObject with fields
add temp to list
I am new to android and after going through many tutorials I still can't get things.
I have created a database and is now reading this database.
This database and 3 columns All three string type.
Now I want to show this database using ListView.I have this ListView
created with id "listDatabaseItems" in R.layout.viewDatabase
Currently my code is:
Cursor c = sqliteDatabase.query(MY_DATABASE_TABLE, null, null, null, null, null, null);
int firstNameColumn = c.getColumnIndex("name_column");
int protectedColumn = c.getColumnIndex("protected_id_column");
ArrayList<String> results = new ArrayList<String>();
int i = 0;
c.moveToFirst();
do {
i++;
String firstName = c.getString(firstNameColumn);
String protectedID = c.getString(protectedColumn);
results.add(firstName + protectedID); // NEED TO add here
} while (c.moveToNext());
sqliteDatabase.close();
Please tell me what changes I do and how can I show my database in ListView.
Best Regards.
Make a Adapter add your ListArray values to it, and then setAdapter to your listview simple,
After your code, add just two lines,
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, results);
mListView.setAdapter(adapter);
Also, your question sounds basic for android So just look at these links..
SimpleCursorAdapters and ListViews
Android SQLite Database and ContentProvider - Tutorial
Filling the Layout with Data
Since you're using a Cursor in the first place, I'd actually go with a SimpleCursorAdapter. A CursorAdapter allows you to avoid loading the whole data set into memory, making initial load times faster and avoiding huge allocations with large data sets.
To expand on the basic setup in this post (SimpleCursorAdapters and ListViews), You'll also want to set a view binder to customize the way data is bound to the view, ie. concatenate your two strings.
Something like this:
SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
//you're only using one view, so we can ignore columnIndex
TextView text = view.findViewById(R.id.list_item_text);
//the cursor is already in position for this list item
int firstNameColumn = c.getColumnIndex("name_column");
int protectedColumn = c.getColumnIndex("protected_id_column");
String firstName = c.getString(firstNameColumn);
String protectedID = c.getString(protectedColumn);
text.setText(firstName+protectedID);
return true; //we have handled binding the data
}
};
Then when you set up your adapter, you pass it a layout that can be used for each item. The layout should contain a TextView to hold the one text item you want to show. You may be able to use android.R.layout.simple_list_item_1 for this as user370305 suggested, but I'm not sure what the id of its TextView is -- it might be android.R.id.text1.
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
context, //can be your Activity
R.layout.list_item, //xml layout containing textview with id 'list_item_text'
c, //the cursor
new String[] {"name_column"}, //the column to read (we'll do more in the binder)
new int[] {R.id.list_item_text}, //the view to hold the data
0 //no flags
);
adapter.setViewBinder(binder);
Add it to your ListView the same way:
ListView listView = //your ListView reference
listView.setAdapter(adapter);
//or in a ListActivity:
setListAdapter(adapter);