i use the following code to list few items from array , while scrolling the list view items is append more with same data exit in array i don`t know what mistake i made.
Anyone pointed out where i made the mistake.
private static String array_spinner_subcategories[];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.sub_categories);
setSubCat();
ListView sub_categories=(ListView)findViewById(R.id.sub_catlist);
sub_categories.setAdapter(new EfficientAdapter(this));
sub_categories.setAdapter(adapter);
sub_categories.setOnItemClickListener(subcatlistener);
cr=getContentResolver();
}
public String[] setSubCat(){
recordDB=new Viddatabase(this);
db=recordDB.getWritableDatabase();
array_spinner_subcategories=recordDB.subcategoriesList(db);
recordDB.close();
return array_spinner_subcategories;
}
private OnItemClickListener subcatlistener = new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position,
long id) {
System.gc();
Toast.makeText(SubCategories.this,array_spinner_subcategories[position],
Toast.LENGTH_LONG).show();
}
};
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return array_spinner_subcategories.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.albumlist, null);
holder = new ViewHolder();
holder.subCategories = (TextView) convertView.findViewById(R.id.albumDetails);
holder.subCategories.setText(array_spinner_subcategories[position]);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
static class ViewHolder {
TextView subCategories;
}
}
Move the holder.subCategories.setText(array_spinner_subcategories[position]); line in getView() method below the else block
In your getView method, you are only setting data in the view when you create a new view.
The ListView recycles views, so you will very likely be passed in a a view to reuse, which is why it is referred to as a convertview.
You need to be calling setText on the view every time this is called, otherwise you are just handing back the convertview unchanged and thus you are getting the same values repeated.
Related
I know that question is stupid, but I need to create Spinner using Realm and get one column for this.
All I want is get one all columt to String array to use ArrayAdapter. How can I get this column? Or maybe the better way is extend ArrayAdapter where I will get all rows from that column using a loop? Tell me, please, the better solution.
There are special Adapters for Realm:
Documentation: https://realm.io/docs/java/latest/#adapters
Project-Page: https://github.com/realm/realm-android-adapters
Example-Code: https://github.com/realm/realm-android-adapters/blob/master/example/src/main/java/io/realm/examples/adapters/ui/listview/MyListAdapter.java
Example code:
public class MyListAdapter extends RealmBaseAdapter<TimeStamp> implements ListAdapter {
private static class ViewHolder {
TextView timestamp;
}
public MyListAdapter(OrderedRealmCollection<TimeStamp> realmResults) {
super(realmResults);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
viewHolder = new ViewHolder();
viewHolder.timestamp = (TextView) convertView.findViewById(android.R.id.text1);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
TimeStamp item = adapterData.get(position);
viewHolder.timestamp.setText(item.getTimeStamp());
return convertView;
}
}
If you truly want to reinvent the wheel, then you should avoid ArrayAdapter in the first place. After all, it handles the actual binding between your elements and your views, which means you learn less!
So if you want to learn, you should create a BaseAdapter. With this, we'll recreate the RealmBaseAdapter.
Okay, so how it works is that you can extend BaseAdapter which expects the following methods:
public class MyAdapter extends BaseAdapter {
#Override
public int getCount() {
// return count;
}
#Override
public Object getItem(int position) {
// return item at position;
}
#Override
public long getItemId(int position) {
// return unique identifier at position index
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// implement view holder pattern
// bind view holder with data at position
// return bound view
}
}
And a RealmBaseAdapter also gives you a RealmChangeListener that is appended to a RealmResults that you provide on creation.
So your case would look like this
public class YourAdapter extends BaseAdapter {
RealmResults<YourObject> results;
final RealmChangeListener realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object element) {
notifyDataSetChanged();
}
};
public YourAdapter(RealmResults<YourObject> results) {
this.results = results;
results.addChangeListener(realmChangeListener);
}
public void updateData(RealmResults<YourObject> results) {
if(this.results.isValid()) {
this.results.removeChangeListener(realmChangeListener);
}
this.results = results;
results.addChangeListener(realmChangeListener);
}
#Override
public int getCount() {
// return count;
if(results == null || !results.isValid()) {
return 0;
}
return results.size();
}
#Override
public YourObject getItem(int position) {
// return item at position;
return results.get(i);
}
#Override
public long getItemId(int position) {
// return unique identifier at position index
return position; // this is sufficient
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// implement view holder pattern
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// bind view holder with data at position
YourObject item = results.get(position);
viewHolder.textView.setText(item.getNeededColumn());
// return bound view
return convertView;
}
private static class ViewHolder {
TextView textView;
public ViewHolder(View view) {
textView = (TextView)view.findViewById(android.R.id.text1);
}
}
}
And then you can do this:
YourAdapter yourAdapter = new YourAdapter(realm.where(YourObject.class).findAll());
listView.setAdapter(yourAdapter);
Although I kinda prefer RecyclerViews lately, but that's ok
My Custom ListView Adapter class like this.
I want to get the index number of an item once an item has been pressed(onclick). How can I get the index number and pass it to a int.. The code where I'll get the index number is after the onCreate method. Please help me!
// On holder.txtstormName_Nice button click i want to get selected item index.
public class ListViewCustomAlerts extends BaseAdapter {
ArrayList<HurricaneBeanClass> itemList;
public Activity context;
public LayoutInflater inflater;
public ListViewCustomAlerts(Activity context,ArrayList<HurricaneBeanClass> arraylist_List)
{
super();
this.context = context;
this.itemList = arraylist_List;
this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount()
{
return itemList.size();
}
#Override
public Object getItem(int position)
{
return itemList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
p =position;
final ViewHolder holder;
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.hurricane_row, null);
holder.txtstormName_Nice=(TextView)convertView.findViewById(R.id.hurricaneNameRowTextView);
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
HurricaneBeanClass bean = (HurricaneBeanClass) itemList.get(position);
holder.txtstormName_Nice.setText(bean.getStormName_Nice());
holder.txtstormName_Nice.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//here i want item index.................
HurricaneBeanClass bean = (HurricaneBeanClass) itemList.get(position);
HurricaneActivity.curlat=bean.getCurentlat();
HurricaneActivity.curlon=bean.getCurentlon();
...
}
});
return convertView;
}
}
public static class ViewHolder
{
TextView txtstormName_Nice;
}
List View Item Position is already coming in argument list.
public View getView(int position, View convertView, ViewGroup parent) {
If you want de id of element you can write in getView:
getItemId(position)
In getView() method you can get it
public View getView(final int position, View convertView, ViewGroup parent) {
.........
.....
System.out.println("Index:"+position);
}
So, here position is your index
I have two ListViews, the second view items change according to what the first user chose in the first ListView
When at first the user choose an item from the first list, the second ListView loads without a problem... but when going back to the first ListView, selecting another item, the second ListView gives the Illegal State Exception...
and I have no idea when to notify the ListView about DataSetChanges because it doesn't make sense to notify it before or after the setListAdapter!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int mIndex = getIntent().getIntExtra("mIndex", 0);
adapter = new mListAdapter(this, getItems(mIndex));
setListAdapter(adapter);
}
Update:
I changed the adapter class and the problem disappeared... This is my old custom class that caused the error... Any idea what is wrong with it?
mListAdapter Class
public class mListAdapter extends BaseAdapter {
private static ArrayList<mItemsHolder> arrayList;
private LayoutInflater mInflater;
Context context;
int textSize;
public mListAdapter (Context m_context, ArrayList<mItemsHolder> results, int mTextSize) {
arrayList = results;
mInflater = LayoutInflater.from(m_context);
context = m_context;
textSize = mTextSize;
}
public int getCount() {
return arrayList.size();
}
public Object getItem(int position) {
return arrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row, null);
holder = new ViewHolder();
holder.mainItem = (TextView) convertView.findViewById(R.id.row_txt_main);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Typeface typeFace=Typeface.createFromAsset(context.getAssets(),"fonts/verdana.ttf");
holder.mainItem.setText(arrayList.get(position).getMainItem());
holder.mainItem.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize);
holder.mainItem.setTypeface(typeFace);
return convertView;
}
static class ViewHolder {
TextView mainItem;
}
}
I just removed "static" when declaring my ArrayList in
private static ArrayList<mItemsHolder> arrayList;
I have a custom listview and i am selecting multiple items in the list, now i need to get those item names when clicking on a button the button will calls listfunction() method, you can see this in the below code.
public class Places extends Activity {
private ListView listView;
private static int selectedListItem = -1;
private Handler mHandler = new Handler();
private static Vector<String> data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_custom_list_view);
data = new Vector<String>();
// Add data as per your requirement
data.add("one");
data.add("two");
data.add("three");
data.add("four");
data.add("five");
data.add("six");
listView = (ListView)findViewById(R.id.ListView01);
listView.setDivider(null);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//System.out.println(EfficientAdapter.saveState.get(position));
selectedListItem = position;
((EfficientAdapter)listView.getAdapter()).notifyDataSetChanged();
if(EfficientAdapter.saveState.get(position)=="selected"){
EfficientAdapter.saveState.put(position,"unselected");
}else
EfficientAdapter.saveState.put(position,"selected");
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// call any new activity here or do any thing you want here
}
}, 200L);
}
});
listView.setAdapter(new EfficientAdapter(getApplicationContext()));
}
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
static HashMap<Integer,String> saveState=new HashMap<Integer,String>();
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
for(int i=0;i<data.size();i++)
{
saveState.put(i,"unselected");
}
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = mInflater.inflate(R.layout.places_custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(saveState.get(position).equals("selected"))
holder.txtName.setBackgroundResource(R.drawable.cellbghover);
else
holder.txtName.setBackgroundResource(R.drawable.cellbgnew);
holder.txtName.setText(data.get(position));
return convertView;
}
}
static class ViewHolder {
TextView txtName;
}
public void listfunction(View button) {
System.out.println("listfunction items are::::"+selectedListItem);
}
}
Custom listview should have custom adapter. In custom adapter you can find method named getView() along with view, position and parentgroup. When you are attempting click event, position will represent the index of the currently selected item.
public class MyArrayAdapter extends ArrayAdapter<String> {
#Override
public View getView(final int position, View convertView,ViewGroup parent) {
}
}
Use a global array to store the index of all the items clicked or touched in the list view by using the following:
listview.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> p, View view, int position,long id) {}
}
);
where position will be the index of the item starting from 0.then after clicking on button use the array to retrieve the positions of the items clicked
How to change the background image for list items, i am able to change only 1 item background at a time.
If there are 6 items on the list and if click on 3 items those 3 items background images should be changed, how it is possible
Below is my code
public class Places extends Activity {
private ListView listView;
private int selectedListItem = -1;
private Handler mHandler = new Handler();
private Vector<String> data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_custom_list_view);
data = new Vector<String>();
// Add data as per your requirement
data.add("one");
data.add("two");
data.add("three");
data.add("four");
data.add("five");
listView = (ListView)findViewById(R.id.ListView01);
listView.setDivider(null);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
selectedListItem = position;
((EfficientAdapter)listView.getAdapter()).notifyDataSetChanged();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// call any new activity here or do any thing you want here
}
}, 200L);
}
});
listView.setAdapter(new EfficientAdapter(getApplicationContext()));
}
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = mInflater.inflate(R.layout.places_custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(position == selectedListItem) {
holder.txtName.setBackgroundResource(R.drawable.cellbghover);
} else {
holder.txtName.setBackgroundResource(R.drawable.cellbgnew);
}
holder.txtName.setText(data.get(position));
return convertView;
}
}
static class ViewHolder {
TextView txtName;
}
Try this,it should work logically.(I didn't try it,btw! :P)
...
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
EfficientAdapter.saveState.put(position,"selected");
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// call any new activity here or do any thing you want here
}
}, 200L);
}
});
...
private class EfficientAdapter extends BaseAdapter {
public static HashMap<Integer,String> saveState=new HashMap<Integer,String>();
private LayoutInflater mInflater;
public EfficientAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
for(int i=0;i<5;i++)
{
saveState.put(i,"unselected");
}
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = mInflater.inflate(R.layout.places_custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(saveState.get(position).equals("selected"))
holder.txtName.setBackgroundResource(R.drawable.cellbghover);
else
holder.txtName.setBackgroundResource(R.drawable.cellbgnew);
holder.txtName.setText(data.get(position));
return convertView;
}
}
static class ViewHolder {
TextView txtName;
}
Every time you click on listview item whole listview is getting refreshed.
So if you want to show previously selected items also then need to keep record of all the item selected. and when listview refreshed you need to check that this positions are previously selected or not according to that set your color.
Hope this help you
try this
android:background="#drawable/img_list_background_repeater"
if(clickWord.size()!=0)
{
for(int i = 0;i<clickWord.size();i++){
if(clickWord.get(i).equalsIgnoreCase(adListText[position])&&clickIndex.get(i)==position){
wordChk.setBackgroundResource(R.drawable.star_1);
}
}
}
Here clickWord is an arraylist of items selected. so when items get selected it will be added in this arraylist and when arraylist is refreshed i check all this using this loop.