can somebody give me an example on how to section the listview?
im using SimpleCursorAdapter to display the datas in the listview..
my code is like this.
private WordDbAdapter dbHelper;
private SimpleCursorAdapter dataAdapter;
this are the codes on the onCreate() method.
dbHelper = new WordDbAdapter(this);
dbHelper.open();
//Clean all data
dbHelper.deleteAllWords();
//Add some data
dbHelper.insertSomeWords();
//Generate ListView from SQLite Database
displayListView();
and this is the code outside the onCreate method.
#SuppressWarnings("deprecation")
private void displayListView() {
Cursor cursor = dbHelper.fetchAllWords();
// The desired columns to be bound
String[] columns = new String[] {
WordDbAdapter.KEY_WORD,
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.Word,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.word_info,
cursor,
columns,
to
);
ListView listView = (ListView) findViewById(R.id.Diclist);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the word name from this row in the database.
String wordSelected =
cursor.getString(cursor.getColumnIndexOrThrow("word"));
String wordSyllabication =
cursor.getString(cursor.getColumnIndexOrThrow("syllabication"));
String wordPartofSpeech =
cursor.getString(cursor.getColumnIndexOrThrow("partofspeech"));
String wordMeaning =
cursor.getString(cursor.getColumnIndexOrThrow("meaning"));
EditText TextDic = (EditText) findViewById(R.id.TextDic);
TextDic.setText(wordSelected);
Toast.makeText(getApplicationContext(),
wordSyllabication + "\n" + wordPartofSpeech + "\n" + wordMeaning , Toast.LENGTH_SHORT).show();
}
});
I found a good example of sectioned listview on this blog.It is done by using ArrayAdapter but you can see the concept and try to manipulate the code accordingly to make it work with SimpleCursorAdapter.
I hope it will be helpful !!
This is tricky with a cursor adapter as you have to remap your positions. I've made a library called SectionCursorAdapter to help with this. It's really easy to implement. To get this to work with your data, when you extend the SectionCursorAdapter just do the following.
#Override
protected Object getSectionFromCursor(Cursor cursor) {
int columnIndex = cursor.getColumnIndex("word");
String word = cursor.getString(columnIndex);
return word.toUpperCase().substring(0, 1);
}
Right now you don't have to worry about recycling your views but you do have to bind the data yourself. If this library gets popular enough I will add a SimpleSectionCursorAdapter.
Related
Hello. There is a table from which data is displayed in ListView by position. Everything works great. But if there are spaces in the table, then this becomes a problem. How can I switch to the desired activity by _id in the table, and not by position?
I ask for help, I will be very grateful.
Thank you all very much!
Below is my code:
This is my code MainActivity.java
this.listView = findViewById(R.id.listView);
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
databaseAccess.open();
List<String> quotes = databaseAccess.getQuotes();
databaseAccess.close();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, quotes);
this.listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(id==0){
Intent myintent = new
Intent(view.getContext(),MosObl.class);
startActivityForResult(myintent,0);
}
if(id==1){
Intent myintent = new
Intent(view.getContext(),Arhangelsk.class);
startActivityForResult(myintent,1);
}
if(id==2){
Intent myintent = new
Intent(view.getContext(),Astrahan.class);
startActivityForResult(myintent,2);
}
This is my code DatabasesAccess.java
public List<String> getQuotes() {
List<String> list = new ArrayList<>();
Cursor cursor = database.rawQuery("SELECT * FROM regiones where izbrannoe = 1", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
list.add(cursor.getString(0));
cursor.moveToNext();
}
cursor.close();
return list;
}
With the position of the clicked item (which is the only thing you will be able to get directly), you can get the quote from your list "quotes", using :
final String desiredQuote = quotes.get(position);
Then, making a request to your database you'll be able to get the desired id. Something like:
final Cursor cursor = database.rawQuery("SELECT _id FROM regiones where izbrannoe = 1 AND quote=?",new String [] {desiredQuote});
Is that what you're looking for?
I'm trying to make an application with drawer menu and one of the option is to open an Activity with Tabs. In every fragment im trying to show listview which oparate on database. I've got problem with too much work on main thread. It is skipped 66 frames or more. I should make this operation in Async Task ? Please help find my a solution what should i do?
public class test1 extends Fragment{
private OpenHelper1 dbHelper;
private SimpleCursorAdapter dataAdapter;
public ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.trening_activity_main, container, false);
dbHelper = new OpenHelper1(this.getActivity());
dbHelper.open();
//Clean all data
dbHelper.deleteAllCountries();
//Add some data
dbHelper.insertSomeCountries();
//Generate ListView from SQLite Database
displayListView(rootView);
return rootView;
}
private void displayListView(View root) {
Cursor cursor = dbHelper.fetchAllCountries();
// The desired columns to be bound
String[] columns = new String[]{
OpenHelper1.KEY_NAME,
OpenHelper1.KEY_KIND
};
// the XML defined views which the data will be bound to
int[] to = new int[]{
R.id.name,
R.id.kind,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
getActivity(), R.layout.trening_activity1,
cursor,
columns,
to,
0);
listView = (ListView) root.findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String countryCode =
cursor.getString(cursor.getColumnIndexOrThrow("name"));
Toast.makeText(getActivity().getApplicationContext(),
countryCode, Toast.LENGTH_SHORT).show();
// Launching new Activity on selecting single List Item
Intent i = new Intent(getActivity().getApplicationContext(), SingleListItem.class);
// sending data to new activity
i.putExtra("cwiczenie ", countryCode);
startActivity(i);
}
});
EditText myFilter = (EditText) root.findViewById(R.id.myFilter);
myFilter.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
dataAdapter.getFilter().filter(s.toString());
}
});
dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return dbHelper.fetchCountriesByName(constraint.toString());
}
});}
}
You can't make database operations in the Main thread (or UI thread). You have to do this in another thread using an AsyncTask. So you already have the answer yourself.
You should use a Loader, a CursorLoader to be exact. This will fetch the data from the database in a background thread. A callback method onLoadFinished will provide the cursor which you can then use to create/update your SimpleCursorAdapter.
Check out the example on the Developer site
I'm trying to set a ListView and I was able to do it using a simple String[] Array as you can see in the code.
Later on, I commented out the Array and used a List
My problem starts when I want to use the List (since I need to manipulate the contents) and a simple Array can't be dynamically changed.
When I use the List I get a NullPointerException when I create the ArrayAdapter and I don't know why.
I read in the documentation of the ArrayAdapter that it is overloaded with 6 different constructors and one of them is
ArrayAdapter(Context context, int resource, List objects)
Why am I getting the NullPointerException?
What should I do to make it work with a List instead of an Array?
Thanks in advance!
public class MainActivity extends Activity implements OnItemClickListener {
ListView l;
// String[] days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
List<String> days;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
days.add(0, "Sunday");
days.add(1, "Monday");
days.add(2, "Tuesday");
days.add(3, "Wednesday");
days.add(4, "Thursday");
days.add(5, "Friday");
days.add(6, "Saturday");
l = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, days);
l.setAdapter(adapter);
l.setOnItemClickListener(this);
}
#Override
public void onItemClick(
AdapterView<?> adapterView, // ListView that was clicked
View view, // Reference to the row that was clicked (each row is a TextView)
int i, // position
long l) { // id of the TextView that was clicked
Toast.makeText(this, days.get(i) + " " + i, Toast.LENGTH_LONG).show();
}
}
You forgot to initialise the days field with anything, so it remains null when you call the add method. Before the days.add(0, "Sunday"); line, add this:
days = new ArrayList<String>();
Also, take out the index numbers. Just use days.add("Sunday"); days.add("Monday");, and so on.
You need to create days:
List<String> days = new ArrayList<String>();
for example.
What I am trying to do is display the contents of the database in a ListView. The layout contains a ListView which I have used and implemented but I can't seem to get them working together (or even the cursor), could someone give me a hand and an explanation of why my cursor implementation doesn't work?
I have a method to return the database entries as a Cursor:
public Cursor getAllRecords() {
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TEXT}, null, null, null, null, null);
}
I have the class where I want to insert and display the database entries:
Button add;
EditText tM;
ListView generalList;
DBAdapter dba = new DBAdapter(this);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_general);
add = (Button) findViewById(R.id.button1);
tM = (EditText) findViewById(R.id.editText1);
generalList = (ListView) findViewById(R.id.generalList);
Cursor c = dba.getAllRecords();
c.moveToFirst();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.id.generalList, c, new String[] {dba.KEY_TEXT}, new int[] {R.id.generalList}, 0);
// This doesn't seem to work for me, I don't know how to fix it
// or how to then get it working with the ListView
generalList.setAdapter(adapter);
add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
insertIntoDatabase();
}
});
}
public void insertIntoDatabase() {
dba.open();
dba.insertRecord(textMessage.getText().toString());
Toast.makeText(this, "Added:\n" + tM.getText().toString(), Toast.LENGTH_LONG).show();
dba.close();
}
When using a ListView with a CursorAdapter, the Cursor returned from the column must contain a column with the name _id uniquely identifying each row. I'm guessing that the one column you are fetching (dba.KEY_TEXT) is not named "_id". You can either add a column to your table named _id or when you perform your SELECT have the database return the name as _id
i.e.
SELECT col_name as _id FROM my_table;
OR
SELECT col_name _id FROM my_table;
if the list contains only 1 TextView, you can use android.R.layout.simple_list_item_1 instead of your R.id.generalList.
and change the new int[] {R.id.generalList} to new int[] {android.R.id.text1}
like :
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, c, new String[] {dba.KEY_TEXT}, new int[] {android.R.id.text1}, 0);
on the arguments that receives the simplecursoradapter, remember the layout it receives is the layout for the actual item not the listview. so remove the R.id.generalList from there, cause that is the id that identified the listview not a full layout. so replace that with a layout that contains a textview. now, on the int array goes the id of the textview that will show the text you want and on the string array pass on the names of the fields in the record read from the database. do as mentioned by aprian and know that you can customize items as much as you need.
I have been tryng to get my search function working ever since adopting TabHosts and I have figured out that in my onCreate method for my Search class that when setContentView(R.layout.main); it causes the following error
03-30 09:19:53.301: E/AndroidRuntime(728): android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord#4053c270 is not valid; is your activity running?
When I comment it out though the search dialog pops up when you click on the hardware search button and I can type a value and press search but then I get the next stumbling block
03-30 09:23:37.061: D/PhoneWindow(776): couldn't save which view has focus because the focused view com.android.internal.policy.impl.PhoneWindow$DecorView#4053ff38 has no id.
Below is my code as it is at the moment for my Search class
public class Search extends ListActivity {
private TextView mTextView;
//protected ListAdapter adapter;
private DxDbAdapter mDbHelper;
DxSimpleCursorAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
//mTextView = (TextView) findViewById(R.id.text1);
// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}
}
public void doMySearch(String query_results) {
//SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
mDbHelper = new DxDbAdapter(this);
mDbHelper.open();
String[] columns = new String[] {"diagnosis", "diagcode"};
int[] to = new int[] {R.id.diagnosis, R.id.code};
// Add "No Results Found" message
Cursor cursor = mDbHelper.search(query_results.trim());
//Cursor cursor = db.rawQuery("Select _id, diagnosis, diagcode From DiagLookup Where diagnosis Like ? order by diagnosis asc", new String[]{"%"+query_results.trim()+"%"});
/* if (cursor == null) {
mTextView.setText(getString(R.string.no_results, new Object[] {query_results}));
}
else {*/
adapter = new DxSimpleCursorAdapter(this,R.layout.list_detail,cursor,columns,to);
setListAdapter(adapter);
// }
}
public void onListItemClick(ListView parent, View view, int position, long id) {
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor c = (Cursor) getListAdapter().getItem(position);
String arg = c.getString(c.getColumnIndex("_id"));
Cursor cursor = db.rawQuery("Select category, subcategory From DiagLookup Where _id = ?", new String[]{""+arg});
cursor.moveToFirst();
Context context = getApplicationContext();
CharSequence text = "Category: " + cursor.getString(cursor.getColumnIndex("category")) + "\nSubcategory: " + cursor.getString(cursor.getColumnIndex("subcategory"));
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
Furthermore I created a custom SimpleCursorAdapter so I can do some actions to an imageview. When I originally had entered adapter = new SimpleCursorAdapter(this,R.layout.list_detail,cursor,columns,to); entering a search term and pressing on the search button had populated the listview but my imageview was not functioning so when I just changed the code to adapter = new DxSimpleCursorAdapter(this,R.layout.list_detail,cursor,columns,to); and added on the top DxSimpleCursorAdapter adapter; it no longer worked and caused the couldn't save focus error.
I am using TabActivity and ActivityGroup to create tabs along the top of my app and I think my context is messed up which is causing the focus to be lost...I am not sure though.
Anyone with some guidance on how I can go about solving these issues?
Thanks in advance.
If you are using TabActivity, why use the ListActivity again? If you want to use the ListView inside the Tabs, you can simply define it in the layout xml file.
If you want to use the Tabs inside an activity, then try this out, Android: TabHost without TabActivity
Switch to ViewPager instead of TabActivity Set default page for ViewPager in Android