Android Studio: Display ArrayList of SQLite database rows using ListView - java

I have an SQLite database and I want to display each ROW/Campsite using ListView.
DBHandler method to return an ArrayList of Campsites:
public ArrayList<Campsite> getAllCampsites() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_CAMPSITES, null);
ArrayList<Campsite> campsites = new ArrayList<>();
Campsite campsite;
if (cursor.getCount() > 0) {
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
campsite = new Campsite();
campsite.setName(cursor.getString(1));
campsite.setCity(cursor.getString(2));
campsite.setFeature(cursor.getString(3));
campsite.setFavorite(cursor.getString(4));
campsite.setRating(cursor.getInt(5));
campsite.setLatitude(cursor.getDouble(6));
campsite.setLongitude(cursor.getDouble(7));
campsites.add(campsite);
}
}
cursor.close();
db.close();
return campsites;
}
I have an activity called Browse which has the ListView in the layout file. I also have a browse_row_layout which has the layout for one row/campsite.
So in Browse.java I need to create the adapter to show each campsite.
Note: I am only showing 3 specific columns (name, city, feature) in the list view
So I have the activity_browse layout file which has the actual ListView element and the browse_row_layout which represents 1 row of the database and has TextViews for only 3 of the columns.
What I have so far:
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class Browse extends AppCompatActivity {
ListView lvCampsites;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browse);
lvCampsites= findViewById(R.id.lvCampsites);
DatabaseHandler db = new DatabaseHandler(this);
ArrayList<Campsite> campsites = db.getAllCampsites();
}
}
TLDR: How can I create an adapter to show each campsite from the campsite list which has each row of the database, using ListView.

Create a custom adapter class that extends the BaseAdapter and then implement the methods and then in the getView method pass the layout id to the view so that u can access the textview in the layout file.
public class CampsitesListAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Campsites> list;
public CampsitesListAdapter(Context mContext , List<Campsites> countries) {
this.mContext = mContext;
this.list = countries;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(mContext, R.layout.campsite_layout , null );
TextView name = (TextView) view.findViewById(R.id.nametxt);
Textview city = (Textview) view.findViewById(R.id.citytxt);
Textview feature = (Textview) view.findViewById(R.id.featuretxt);
name.setText(list.get(position).getname());
city.setText(list.get(position).getcity());
feature.setText(list.get(position).getfeature());
return view;
}
}
This is your listview activity
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class Browse extends AppCompatActivity {
ListView lvCampsites;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browse);
lvCampsites= findViewById(R.id.lvCampsites);
DatabaseHandler db = new DatabaseHandler(this);
ArrayList<Campsite> campsites = db.getAllCampsites();
//Instance of custom adapter
CampsitesListAdapter adapter = new CampsitesListAdapter(this , campsites);
//Setting adapter to listview
lvCampsites.setAdapter(adapter);
}
I hope this might help you.

You need to first move your cursor. refer below code:
if (cursor!=null && cursor.getCount()> 0){
cursor.moveToFirst();
do{
Campsite campsite = new Campsite();
campsite.setName(cursor.getString(1));
campsite.setCity(cursor.getString(2));
campsite.setFeature(cursor.getString(3));
campsite.setFavorite(cursor.getString(4));
campsite.setRating(cursor.getInt(5));
campsite.setLatitude(cursor.getDouble(6));
campsite.setLongitude(cursor.getDouble(7));
campsites.add(campsite);
}while(cursor.moveToNext);
}

Related

How to fix "System services not available to Activities before onCreate" when passing values between classes, and updating recycler view?

I'm making an order taking cashier application. Using a recycler view to show the order queue. However, I'm having trouble passing ArrayList values between classes, and also, updating the recycler view. In this case, I won't have a massive recycler view so performance wouldn't be that much of an issue, but an optimized method of doing this would be greatly appreciated. I just don't know how to tackle this problem.
I've attempted to create a set method in the MainActivty class, I've also tried the intent put extra, but I don't believe I fully understand put extra quite yet.
MainActivity Class:
public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
public ArrayList<String> orderList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// set up the RecyclerView
recyclerView = findViewById(R.id.recyle_view_activity);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new MyRecyclerViewAdapter(this, orderList);
((MyRecyclerViewAdapter) mAdapter).setClickListener(this);
recyclerView.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(mAdapter);
}
//This is the set method I attempted:
public void setOrderAdd(ArrayList<String> data){
if (data != null){
mAdapter = new MyRecyclerViewAdapter(this,data); //Error refrences here
}
}
}
Other Class:
public class regularCoffee extends AppCompatActivity implements AdapterView.OnItemSelectedListener, Serializable {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_regular_coffee);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
addToOrder();
}
public void addToOrder(){
//Reg Addons:
final CheckBox leaveRoomReg = findViewById(R.id.leave_room_reg);
final CheckBox cinnamonReg = findViewById(R.id.cinnamon_reg);
final CheckBox chocolateSyrupReg = findViewById(R.id.chocolate_syrup_reg);
final CheckBox whiteChocolateSyrupReg = findViewById(R.id.white_chocolate_syrup_reg);
final CheckBox caramelReg = findViewById(R.id.caramelReg);
final CheckBox hazelnutReg = findViewById(R.id.hazel_nut_reg);
final CheckBox[] RegCoffeeAddOns = {leaveRoomReg,cinnamonReg,chocolateSyrupReg,whiteChocolateSyrupReg,caramelReg,hazelnutReg};
//Decaf Addons:
final Button leaveRoomDecaf = findViewById(R.id.leave_room_decaf);
final Button cinnamonDecaf = findViewById(R.id.cinnamon_decaf);
final Button chocolateSyrupDecaf = findViewById(R.id.chocolate_syrup_decaf);
final Button whiteChocolateDecaf = findViewById(R.id.white_chocolate_syrup_decaf);
final Button caramelDecaf = findViewById(R.id.caramel_decaf);
final Button hazelnutDecaf = findViewById(R.id.hazel_nut_decaf);
final Button[] DecafCoffeeAddOns = {leaveRoomDecaf,cinnamonDecaf,caramelDecaf,chocolateSyrupDecaf,whiteChocolateDecaf,hazelnutDecaf};
Button addToOrderButton = findViewById(R.id.addToOrderReg);
addToOrderButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity addToOrderArea = new MainActivity();
String forOrder;
ArrayList<String> tempArray = new ArrayList<>();
if (regCoffeeQuantity > 0){
forOrder = "Regular Coffee (x" + regCoffeeQuantity + ") \n ";
for (int i = 0; i < RegCoffeeAddOns.length; i++){
if (RegCoffeeAddOns[i].isChecked()){
forOrder = forOrder + "| " + RegCoffeeAddOns[i].getText().toString() + " ";
System.out.println(forOrder);
}
}
addToOrderArea.setOrderAdd(tempArray); //Error refrences here
}
}
});
}
RecyclerView Adapter:
package com.example.holygroundsapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
MyRecyclerViewAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context); //Error refrences here.
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
void setClickListener(MainActivity itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
This is the error:
java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:5774)
at android.view.LayoutInflater.from(LayoutInflater.java:233)
at com.example.holygroundsapplication.MyRecyclerViewAdapter.<init>(MyRecyclerViewAdapter.java:21)
at com.example.holygroundsapplication.MainActivity.setOrderAdd(MainActivity.java:89)
at com.example.holygroundsapplication.regularCoffee$8.onClick(regularCoffee.java:262)
...
In your onClick function you have
MainActivity addToOrderArea = new MainActivity();
You shouldn't create activity instances by your self. This is something the Android system does. Because you create the activity by yourself it is not initialized (i.e. onCreate() is not called). The adapter which is created in the setOrderAdd() requires that the Activity is initialized and therefore throws an exception.
To prevent these problems you need to create your Activity with startActivity(). You can pass your data to the new Activity by adding extras to the starting Intent.
I think you logically need to replace
MainActivity addToOrderArea = new MainActivity();
with
MainActivity addToOrderArea = MainActivity.this;
But since you are not in the same class you need to pass the reference accordingly.
As long the MainActivity is still active and the other class is just a helper that wouldn't be a problem. Just add MainActivity to all the constructors... Somewhat like this:
OtherClass{
private MainClass addToOrderArea;
public OtherClass(MainClass addToOrderArea){
this.addToOrderArea=addToOrderArea;
}
// ...
abstract class MyOnclicklistener extends View.OnClickListene{
private MainClass addToOrderArea;
public MyOnclicklistener(MainClass addToOrderArea){
this.addToOrderArea=addToOrderArea;
}
}
// ...
addToOrderButton.setOnClickListener(new MyOnclicklistener(this.addToOrderArea) {
#Override
public void onClick(View v) {
String forOrder;
ArrayList<String> tempArray = new ArrayList<>();
if (regCoffeeQuantity > 0){
forOrder = "Regular Coffee (x" + regCoffeeQuantity + ") \n ";
for (int i = 0; i < RegCoffeeAddOns.length; i++){
if (RegCoffeeAddOns[i].isChecked()){
forOrder = forOrder + "| " + RegCoffeeAddOns[i].getText().toString() + " ";
System.out.println(forOrder);
}
}
addToOrderArea.setOrderAdd(tempArray); //Error refrences here
}
}
});
}
Attention: i guess this might still get you into another error, since you try to edit one activity from another...
Propably only store the variable between both activities, that seems okay. Updating the recycler view directly from another activity however might get you into some android view or security errors. I would say just pass the variable and update the recyclerview in the onResume function later. Something like this:
private ArrayList<String> _data;
public void setOrderAdd(ArrayList<String> data){
if (data != null){
// only store variable
_data = data;
}
}
#Override
protected void onResume() {
super.onResume();
// make update of your viewing components here
if(_data!=null){
mAdapter = new MyRecyclerViewAdapter(this,_data);
}
}
Now it should work i guess

how can i make the user be able to edit item in list view in android

i have a listView and every item is a textView , and a dataBase contains 3 columns ( "ID"- "NAME" - "TAG" ) , what is showable in the list view is the name , the user enter it in the editBox and the tag associated with it and stored in the dataBase now i want when the user do a long click on each item opens a new activity contain 2 editbox one for the name and one for the tag and enter them so will update that one already clicked on it ..
here is my code
database functions class :
package com.chaos.twittertask;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DataBase {
private SQLiteDatabase mDatabase;
private DB_Helper helper;
public DataBase(Context context) {
helper = new DB_Helper(context);
}
protected void open() {
mDatabase = helper.getWritableDatabase();
}
public void close() {
if (mDatabase != null) {
mDatabase.close();
}
}
public Cursor getAllNames()
{
String[] col = { "NAME" };
Cursor cursor = mDatabase.query(
"task", // table name
col, // column names
null, // where clause
null, // where params
null, // groupby
null, // having
null // orderby
);
return cursor;
}
public Cursor getTagByID(int id) {
String[] columns = { "TAG"};
return mDatabase.query(
"task", // table name
columns, // column names
"ID" + " = " + id, // where clause // id param. could be here or appended as it is ^
null, // where params
null, // groupby
null, // having
null // orderby
);
}
public void insertTagAndName(String name,String tag) {
ContentValues newTask = new ContentValues();
newTask.put("NAME", name);
newTask.put("TAG",tag);
mDatabase.insert("task", null, newTask);
}
public void updateNameAndTag(int id,String name,String tag) {
ContentValues editTask = new ContentValues();
editTask.put("NAME", name);
editTask.put("TAG", tag);
mDatabase.update(
"task", // table name
editTask, // values
"ID" + " = " + id, // where clause
null // where params
);
}
public void getNameId(String name) {
mDatabase.execSQL("SELECT ID from task WHERE NAME="+name);
}
public void deleteTagById(int id) {
mDatabase.delete(
"task", // table name
"ID" + "=" + id, // where clause
null // where params
);
}
}
MatinActivity :
package com.chaos.twittertask;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button save;
private EditText name;
private EditText tag;
private TextView headline;
private ListView list;
private DataBase dataBase;
private String[] names;
private Cursor cursor;
private ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
save= (Button) findViewById(R.id.save);
name=(EditText) findViewById(R.id.name);
tag=(EditText) findViewById(R.id.tag);
headline=(TextView) findViewById(R.id.tagged_searches);
list=(ListView) findViewById(R.id.listView);
dataBase=new DataBase(MainActivity.this);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dataBase.insertTagAndName(name.getText().toString(), tag.getText().toString());
name.setText("");
tag.setText("");
Toast.makeText(MainActivity.this, "Tag has been added successfully ",
Toast.LENGTH_LONG).show();
loadData();
}
});
list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
return false;
}
});
}
protected void onResume() {
super.onResume();
loadData();
}
private void loadData()
{
int i=0;
dataBase.open();
cursor = dataBase.getAllNames();
names = new String[cursor.getCount()];
try {
cursor.moveToFirst();
int index_name = cursor.getColumnIndex("NAME");
do {
names[i] = cursor.getString(index_name);
i++;
}while (cursor.moveToNext());
adapter = new ArrayAdapter<String>(
this,
R.layout.list_item, R.id.name_item,
names);
list.setAdapter(adapter);
}catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}
That's not hard to do.
Your ListView item will contain a TextView, that will be the name.
The best way to do this is creating 2 things, a Custom Adapter and a Dialog Fragment. So lets begin.
Create a new class that will hold the data, in your case it's name and flag.
public class ListItem{
String name;
String flag;
public ListItem(String name, String flag) {
this.name= name;
this.flag= flag;
}
}
Good. Now your Custom Adapter will need an instance of this class instead of a String. It will do the same thing that a regular Adapter but with a ListItem.
Create a new class like this:
public class ListItemAdapter extends ArrayAdapter<ListItem>{
public ListItemAdapter(Context context, List<ListItem> items) {
super(context, 0, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Context context = getContext();
ListItem item = getItem(position);
View rootView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
TextView name = (TextView) rootView.findViewById(R.id.your_text_view_item);
name.setText(item.name);
return rootView;
}
}
Now the Custom Adapter is created. It requires a ListItem that has 2 values, but only uses 1. The other will be used later.
Use a Custom Adapter is just like a normal one. But insted of using String in the the "< >" use ListItem
Now you need a Dialog Fragment that will show your 2 EditTexts.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="#+id/dialog_name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="4dp"/>
<EditText
android:id="#+id/dialog_flag_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="4dp"
android:inputType="textPassword"" />
You will pass the data from the Fragment to your Activity trought an Interface's abstract method. Just like this:
public interface MyCallback{
void callback(String name, String flag);
}
public class ListViewDialogFragment extends DialogFragment {
MyCallback myCallback;
EditText nameEditText;
EditText flagEditText;
public ListViewDialogFragment() {
}
public static ListViewDialogFragment newInstance(String title, MyCallback callback){
ListViewDialogFragment fragment = new ListViewDialogFragment ();
Bundle args = new Bundle();
args.putString("title", title);
fragment.setArguments(args);
myCallback = callback;
return fragment;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View rootView = getActivity().getLayoutInflater().inflate(R.layout.xml_we_just_created, null);
nameEditText= (EditText) rootView.findViewById(R.id.dialog_name_edit_text);
flagEditText= (EditText) rootView.findViewById(R.id.dialog_flag_edit_text);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(rootView);
String title = getArguments().getString("title");
builder.setTitle(title);
builder.setPositiveButton("Confirmar", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String name = nameEditText.getText.toString();
String flag = flagEditText.getText.toString();
if(!name.equals("") && !flag.equals(""))
myCallback.callback(name, flag);
}
});
}
}
Great! Now you need to call this whenever you want to edit the listItem.
The way to call is:
ListViewDialogFragment fragment = ListViewDialogFragment.newInstance("Your_Title", new ListViewDialogFragment.MyCallback(){
#Override
public void callback(String name, String flag){
//Do whatever you want with the name and flag.
//You can create a ListItem with these 2 and update your adapter.
}
});
fragment.show(getFragmentManager(), "");
And to send the data to the database just do:
adapter.getItem(i).name;
and
adapter.getItem(i).flag;
Where "i" is the index from the ListView. ;)

Android cursor adapter get checkbox and data of listview

I have this code that used cursor adapter:
public class TemplateActivity extends Activity {
Button btnSort, btnDel;
private ListViewAdapter listAdapter;
private RetailerDatabaseHelper dbHelper;
private ListView listView;
private static final String TAG = TemplateActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_template);
btnSort = (Button) findViewById(R.id.btnSort);
btnDel = (Button) findViewById(R.id.btnDelete);
dbHelper = new RetailerDatabaseHelper(this);
listView = (ListView) findViewById(R.id.listViewData);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "clicked on item: " + position);
}
});
new Handler().post(new Runnable() {
#Override
public void run() {
listAdapter = new ListViewAdapter(TemplateActivity.this, dbHelper.getAllData());
listView.setAdapter(listAdapter);
}
});
my problem is that how can i get the value of the data from the listview when a data is clicked.
Here is my adapter for this:
public class ListViewAdapter extends CursorAdapter {
public ListViewAdapter (Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// when the view will be created for first time,
// we need to tell the adapters, how each item will look
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.custom_dialog_box, parent, false);
return retView;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// here we are setting our data
// that means, take the data from the cursor and put it in views
TextView textViewPersonName = (TextView) view.findViewById(R.id.checkBox1);
textViewPersonName.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1))));
TextView textViewPersonPIN = (TextView) view.findViewById(R.id.number);
textViewPersonPIN.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2))));
}
}
another thing. how will i implement here that when i checked a checkbox and press a button it will get the data of the checkbox? thank you all for the help.
I haven't worked on ListViewAdapter but i have the same scenario as yours.
I have used CustomAdapter class extending Baseadapter and using custom layout. By this way you can set OnClicklistners for every view individually(check box,button,total layout... ).
The easiest way to do it in OnItemClickListener is this:
Cursor c = ((ListViewAdapter)l.getAdapter()).getCursor();
c.moveToPosition(position);
You can then use the c.getLong(0); to get the id (assuming you fetched the id column as the first column which is generally the case).
Second question :(Get the checked items list) :
You can write a setOnCheckedChangeListener (CompoundButton.OnCheckedChangeListener listener) for the Checkbox in your bindView() method of your Adapter, then if item is checked then add the item to the list, if it is unchecked then remove the item from the list.

Android: positioning items in ListView menu in java?

I am really new into Android development, so I am sorry if this question may sound funny to some of you.
I need to center the items of my ListView Menu just for the sake of aestheticism, but I really don't know how since the code is written only in java without the use of XML.
package com.example.mysqltest;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Menu extends ListActivity {
String classes[] = {"ProductList", "example1", "example2", "example3", "example4", "example5"};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(Menu.this, android.R.layout.simple_list_item_1, classes));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
String local = classes[position];
try {
Class ourClass = Class.forName("com.example.mysqltest." + local);
Intent ourIntent = new Intent(Menu.this, ourClass);
startActivity(ourIntent);
} catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
You can change the layout you are passing to your adapter here:
setListAdapter(new ArrayAdapter<String>(Menu.this, android.R.layout.simple_list_item_1, classes));
This piece is the layout of the row:
android.R.layout.simple_list_item_1
Check this answer that explains what it is.
You need to create your own Adapter :
public class MyAdapter extends BaseAdapter{
private LayoutInflater inflater;
private List<String> data;
public MyAdapter(Context context, List<String> data){
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.data = data;
}
public int getSize(){
return data.getSize();
}
public Object getItem(int position){
return data.get(position);
}
public View getView(View convertView, int position, ViewGroup parent){
View v = convertView;
ViewHolder h;
if(v == null){
v = inflater.inflate(R.layout.my_adapter, false);
h = new ViewHolder();
t.tv = (TextView) v.findViewById(R.id.my_textview);
v.setTag();
}else{
h = (ViewHolder) v.getTag();
}
String s = (String) getItem(position);
h.tv.setText(s);
return v;
}
public class ViewHolder{
TextView tv;
}
}
I don't really remember by heart because of the autocompletion in Eclipse, but it should look like this.
Your my_adapter.xml is where you will place your TextView everywhere you want, you will be able to add more, like ImageViews and others TextViews.
And to call it it's simple :
MyAdapter adapter = new MyAdapter(context, myList);
listView.setAdapter(adapter);
It's not only written in Java, you have to supply an XML layout for the Adapter to inflate. In your case, you've got R.layout.simple_list_item_1. Where you set it here:
setListAdapter(new ArrayAdapter<String>(Menu.this, android.R.layout.simple_list_item_1, classes));
As you've not posted the content of R.layout.simple_list_item_1 - I have to assume that it's just a TextView that's contained within it. As such, you can quite easily align text with something like the following:
TextView textView =(TextView)findViewById(R.id.texviewid);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
Failing that, you could always set it within the XML of R.layout.simple_list_item_1 and not worry about it.
Hope this helps.
just write this code before setting adapter,here lv is your listview
lv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);

ArrayAdapter is not refreshing itself (only the last element is updated)

As my post states, I can't seem to get my ArrayAdapter to update the whole list despite the call "adapter.notifyDataSetChanged();" Only the last element in the list is updated.
Can someone maby see what I'm doing wrong below??
Here is my custom adapter
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class WeatherAdapter extends ArrayAdapter<Weather>{
Context context;
int layoutResourceId;
Weather data[] = null;
private WeatherHolder holder;
private Weather weather;
public WeatherAdapter(Context context, int layoutResourceId, Weather[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.imgIcon = (TextView)row.findViewById(R.id.imgen);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
weather = data[position];
holder.txtTitle.setText(weather.getName());
//holder.imgIcon.setText(Double.toString(weather.getBuyingRate()));
return row;
}
public void update(String buttonPressed){
if(buttonPressed == "Köp Kurs"){
holder.imgIcon.setText(Double.toString(weather.getBuyingRate()));//This updates only the last element in list but I want to update every element in the list
}
else if(buttonPressed == "Antal"){ holder.imgIcon.setText(Double.toString(weather.getNrOfSharesInPortfolio()));//This updates only the last element in list but I want to update every element in the list
}
}
static class WeatherHolder
{
TextView imgIcon;
TextView txtTitle;
}
}
And here is my main class, when I call "Update()" method only the last element in the list is updated but not the others. How can I update the whole list instead of just the last element in the list?
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView listView1;
private Button goButton;
private String[] listheader = {"Köp Kurs","Antal"};
private WeatherAdapter adapter;
private int totalElemInlist = listheader.length;
private int currentelemInList=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Weather weather_data[] = new Weather[]
{
new Weather("ABB", 56.0, 300),
new Weather("Volvo", 89.0,500),
new Weather("Astra Zeneca", 98.55, 50)
};
adapter = new WeatherAdapter(this,
R.layout.listview_item_row, weather_data);
listView1 = (ListView)findViewById(R.id.listView1);
View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null);
listView1.addHeaderView(header);
goButton = (Button) findViewById(R.id.testButton);
goButton.setText(listheader[currentelemInList]);
listView1.setAdapter(adapter);
goButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
String buttonPressed = (String) ((Button) view).getText();
goThroughList(buttonPressed);
System.out.println("Button Clicked" + buttonPressed);
}
});
}
private void goThroughList(String buttonPressed){
currentelemInList++;
if(currentelemInList>=totalElemInlist){
currentelemInList=0;
}
goButton.setText(listheader[currentelemInList]);
if(buttonPressed == "Köp Kurs"){
System.out.println("Köp kurs");
adapter.update(buttonPressed);
adapter.notifyDataSetChanged();//This only updates the last element in list
}
else if(buttonPressed == "Antal"){
System.out.println("Antal");
adapter.update(buttonPressed);
adapter.notifyDataSetChanged();//This only updates the last element in list
}
System.out.println(currentelemInList);
}
}
How can I update the whole list instead of just the last element in the list?
You must make your changes happen in getView(). getView() redraws every row as they appear whenever the user scrolls the ListView or notifyDataSetChanged() is called. So the changes must happen in there otherwise they will be erased.
First create a new field variable in your adapter:
private String currentImage;
Second change update() to control the contents on imgIcon:
public void update(String buttonPressed){
currentImage = buttonPressed;
notifyDataSetChanged();
}
Last change getView() to display the current images for each row:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
...
weather = data[position];
holder.txtTitle.setText(weather.getName());
if(currentImage.equals("Köp Kurs")){
holder.imgIcon.setText(Double.toString(weather.getBuyingRate()));
}
else if(currentImage.equals("Antal")){
holder.imgIcon.setText(Double.toString(weather.getNrOfSharesInPortfolio()));
}
return row;
}
(You can also simplify goThroughList(), since the if-else contains the exact same code.)
You should compare string like this.
buttonPressed.equals("Köp Kurs")
I might be wrong , but I think problem is because you are holding only last element in your holder. The member variable "holder" in adapter should be array or list, and you should hold all element, and in update method you should iterate through holder array and change the text
public void update(String buttonPressed){
for(int index =0 ; index < holder.size();index++){
if(buttonPressed == "Köp Kurs"){
holder[index].imgIcon.setText(Double.toString(weather.getBuyingRate()));//This updates only the last element in list but I want to update every element in the list
}
else if(buttonPressed == "Antal"){ holder[index].imgIcon.setText(Double.toString(weather.getNrOfSharesInPortfolio()));//This updates only the last element in list but I want to update every element in the list
}
This should solve your problem

Categories