following is my Java code in Android Studio. GUI Layout contain an editText where a word is to be input and then click on search button. After that, it will show the matching words from an array (which contain words) and display those in a listView. The functionality of fetching matching regex from array and then displaying item by item in listView is to be implemented; I need idea about that how to implement it in Finder function.
Example 1:
Array of Words : "Dust", "Duff", "Thrust", "Man", "Grade", "Mole", "Tax"
Input: ust
Output in listView:
Item 1: Dust
Item 2: Thrust
package com.neatsoft.hamqafia;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
EditText textBar;
Button findBtn;
ListView listView;
String words[] = {"Dust", "Duff", "Thrust", "Man", "Grade", "Mole", "Tax"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private void Init(){
textBar = (EditText) findViewById(R.id.editText);
findBtn = (Button) findViewById(R.id.button);
listView = (ListView) findViewById(R.id.listView);
}
private void Finder(String toFind){
//Store Array in Trie Datastructure and then find toFind keyword and show the results item by item in listView
///OR create regex search by any other datastructure or methodology
}
}
when clicked the search button .you can search text in list items with String str1.toLowerCase().contains(str2.toLowerCase()) and save strings that contains search key in another list or array .after that reload data to listview with search list items .
note : you can use another button (clear search) and when click it, assign searchlist variable to initial list and reload data .(no search case)
private void Finder(String toFind){
if(searchList == null) {
searchList = new ArrayList<>();
}
searchList.clear();
if(toFind != null || !toFind.trim().equals("")) {
for(String str : words) {
if(str.toLowerCase().contains(toFind.toLowerCase()))
searchList.add(str);
}
}
notifyDataToListView();
}
private void notifyDataToListView() {
if(adapter == null) {
adapter = new BaseAdapter() {
#Override
public int getCount() {
return searchList == null ? 0 : searchList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = new TextView(getApplicationContext());
}
((TextView) convertView).setText(searchList.get(position));
return null;
}
};
myListView.setAdapter(adapter);
}else {
adapter.notifyDataSetChanged();
}
}
like this.Define a BaseAdapter object globally.
Related
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
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);
}
I'm having this issue with my android custom listview such that everytime i exit the activity (i.e. click the "back" button on emulator), then return back to the same activity that contains this custom listview, the listview adds an additional row to itself.
For example, originally it is:
item a
When I leave that activity and come back to it, the row doubles:
item a
item a
However, when i restart the emulator again, the custom listview goes back to the original number of data retrieved from sqlite.
How do I stop the rows from doubling themselves?
Here are my codes.
list.java:
//DATABASE
MyItems mi;
//For Items display - ArrayList
private ArrayList<SalesItemInformationLV> displayiteminfo;
/* new ArrayList<SalesItemInformationLV>(); */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_sale_item);
final float sellingpvalue = 13.5f;
final float costpvalue = 19.0f;
final String datesoldvalue = "9/9/1995";
final String staffdiscountvalue = "true";
mi = MyItems.getInstance();
displayiteminfo = mi.retrieveAllForlist(getApplicationContext());
//New array adapter for customised ArrayAdapter
final ArrayAdapter<SalesItemInformationLV> adapter = new itemArrayAdapter(this, 0, displayiteminfo);
//displayiteminfo - the ArrayList of item objects to display.
//Find the list view, bind it with custom adapter
final ListView listView = (ListView)findViewById(R.id.customListview);
listView.setAdapter(adapter);
// listView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 9));
//LONG PRESS CONTEXT MENU
registerForContextMenu(listView);
//Selecting the listview item!
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SalesItemInformationLV saleitem = displayiteminfo.get(position);
String namevalue = saleitem.getItemname();
int qtyvalue = saleitem.getItemquantity();
Intent myintent = new Intent(ListSaleItemActivity.this, ViewSaleDetails.class);
myintent.putExtra("itemname", namevalue);
myintent.putExtra("itemqty", qtyvalue);
myintent.putExtra("itemcp", costpvalue);
myintent.putExtra("itemsp", sellingpvalue);
myintent.putExtra("itemds", datesoldvalue);
myintent.putExtra("itemsstaffdis", staffdiscountvalue);
startActivity(myintent);
}
});
}
//custom Arrayadapter
class itemArrayAdapter extends ArrayAdapter<SalesItemInformationLV>
{
private Context context;
private List<SalesItemInformationLV> item;
//constructor, call on creation
public itemArrayAdapter(Context context, int resource, ArrayList<SalesItemInformationLV> objects) {
//chaining to "default constructor" of ArrayAdapter manually
super(context, resource, objects);
this.context = context;
this.item = objects;
}
//called to render the list
public View getView(int position, View convertView, ViewGroup parent)
{
//get the item we are displaying
SalesItemInformationLV iteminfo = item.get(position);
//get the inflater and inflate the xml layout for each item
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item_layout, null);
//Each component of the custom item_layout
TextView name = (TextView) view.findViewById(R.id.ItemNameSales);
TextView qty = (TextView)view.findViewById(R.id.ItemNameQty);
//set the name of item - access using an object!
name.setText(String.valueOf(iteminfo.getItemname()));
//set the quantity of item - access using an object!
qty.setText(String.valueOf(iteminfo.getItemquantity()));
return view;
//Now return to onCreate to use this cuztomized ArrayAdapter
}
}
Myitems.java:
public class MyItems extends Application {
//ID and contact information
private List<String> contactList;
private List<Integer> contactIdList;
private static MyItems ourInstance = new MyItems();
//Populate SaleItemInformationLV
private ArrayList<SalesItemInformationLV> displayiteminfo2 =
new ArrayList<SalesItemInformationLV>();
public MyItems()
{
contactList = new ArrayList<String>();
contactIdList = new ArrayList<Integer>();
}
public static MyItems getInstance(){
return ourInstance;
}
//RETRIEVE ALL ENTRIES
//LISTVIEW
public ArrayList<SalesItemInformationLV> retrieveAllForlist(Context c)
{
Cursor myCursor;
String mystring = "";
MyDbAdapter db = new MyDbAdapter(c);
db.open();
//contactIdList.clear();
//contactList.clear();
myCursor = db.retrieveAllEntriesCursor();
if (myCursor !=null && myCursor.getCount()>0)
{
myCursor.moveToFirst();
do {
displayiteminfo2.add(new SalesItemInformationLV(myCursor.getString(db.COLUMN_NAME_ID), db.COLUMN_QTYSOLD_ID));
} while (myCursor.moveToNext());
}
db.close();
return displayiteminfo2;
}
MyItems is a (java-)singleton. Each times that you call public ArrayList<SalesItemInformationLV> retrieveAllForlist(Context), you add objects in displayiteminfo2 et return this list.
If you call a second times retrieveAllForlist, you keep the same list with objects already in it and add more to it.
It's a bad pattern to return a private instance object in a function. Anything outside of your class can modify the list. Just create one for returning it.
public ArrayList<SalesItemInformationLV> retrieveAllForlist(Context c)
{
ArrayList<SalesItemInformationLV> items = new ArrayList<SalesItemInformationLV>();
Cursor myCursor;
String mystring = "";
MyDbAdapter db = new MyDbAdapter(c);
db.open();
//contactIdList.clear();
//contactList.clear();
myCursor = db.retrieveAllEntriesCursor();
if (myCursor != null && myCursor.getCount() > 0)
{
myCursor.moveToFirst();
do {
items.add(new SalesItemInformationLV(myCursor.getString(db.COLUMN_NAME_ID), db.COLUMN_QTYSOLD_ID));
} while (myCursor.moveToNext());
}
db.close();
return items;
}
It looks like MyItems is a singleton. Are you clearing the values before calling
mi.retrieveAllForlist(getApplicationContext())? If not, you may be doubling up the values when onCreate() is called after returning to the activity.
I have a listview in one of my Activities that has a delete button inside of each row. When I click the delete button I want to remove that row value from two different arrays. The first array is the list array that shows the information in the listview and the second is for my sharedPreference array which is the data populating the listview. This works fine the first time I run it but if I try deleting more than one row without recreating the view it won't work.
Here is my code:
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//this will delete the row from the list view
list.remove(position);
//this deletes the value from the sharedPreference
favoritesList.remove(position);
notifyDataSetChange();
}
}
This works the fine the first time I click the delete button in a row but if I want to delete another row, I click the delete button on a different row and while the row is removed from the listview it isnt removed from my favoritesList array. Which means the favoritesList.remove(postion) is only working the first time. It's almost like favoritesList isn't being refreshed and its just trying to remove the same value no matter what row I click on. Which is weird because list.remove(position) works fine.
So how do I get favoritesList(position) to run more than once without breaking? I can post more code if need be but I figured this would be enough. Any help is appreciated. Thanks!
Here is the whole custom adapter for my listview:
public class ItemCustomAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
ArrayList<String> favoritesList;
private Context context;
//private final SharedPreferences sharedPrefs;
String[] favorites;
public ItemCustomAdapter(ArrayList<String> list, Context context, String[] favorites) {
this.list = list;
this.context = context;
this.favorites = favorites;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return 0;
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
//System.out.println(favoritesList);
favoritesList = new ArrayList<String>(Arrays.asList(favorites));
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_list_view, null);
}
//Handle TextView and display string from your list
TextView listItemText = (TextView)view.findViewById(R.id.list_item_string);
listItemText.setText(list.get(position));
//Handle buttons and add onClickListeners
ImageButton deleteBtn = (ImageButton)view.findViewById(R.id.delete_btn);
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
list.remove(position);
favoritesList.remove(position);
notifyDataSetChanged();
}
});
return view;
}
}
As Opiatefuchs said above, all I had to do was move favoritesList = new ArrayList(Arrays.asList(favorites)); outside of getView().
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