songs getting mixed up in listview - android

i want to get the list of all the music files in android device so i used the following code
public class MusicAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater l_Inflater;
public MusicAdapter(Context c) {
mContext = c;
l_Inflater = LayoutInflater.from(c);
}
public int getCount() {
return count;
}
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();
TextView tv = new TextView(mContext.getApplicationContext());
String id = null;
TextView txt_itemName = null;
if (convertView == null) {
convertView = l_Inflater.inflate(R.layout.menu, null);
txt_itemName = (TextView) convertView.findViewById(R.id.textView1);
ImageView itemImage = (ImageView) convertView.findViewById(R.id.imageView1);
music_column_index = musiccursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
musiccursor.moveToPosition(position);
id = musiccursor.getString(music_column_index);
txt_itemName.setText(id);
} else {}
return convertView;
}
}
everything works fine But when I scroll up and down, the list is mixed up. I tap on an title but it plays the wrong one. Each time I go back to the top of the list, a different song is displayed as the first song. what do i do.. ?? how do i solve this

This is what is wrong:
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
In getItem you need to return an instance that represents your object, maybe something like a Music object. And in the getItemId you need return an unique value for that instance.
Let's pretend that you load an array with Music instances, something like this:
public class MusicAdapter extends BaseAdapter {
public class Music {
private Long id;
private String pathToSd;
private Long lenght;
}
private List<Music> mMusicList;
private LayoutInflater mInflater;
public MusicAdapter(Context context, List<Music> music) {
mMusicList = music;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return mMusicList.size();
}
#Override
public Object getItem(int position) {
return mMusicList.get(position);
}
#Override
public long getItemId(int position) {
return mMusicList.get(position).id; //If you aren't saving your list of music in some place like a db
//and thus, you don't have an id, you can return -1.
}
#Override
public View getView(int position, View convertedView, ViewGroup parent) {
if (convertedView == null) {
convertedView = mInflater.inflate(R.layout.your_layout, null);
}
//Perform your operations over the view here...
}
}
Anyways, I Strongly reccomend you save this list in a db.
Hope it helps :]

This code solved the problem
public class MusicAdapter extends BaseAdapter {
private LayoutInflater l_Inflater;
public MusicAdapter(Context c) {
l_Inflater = LayoutInflater.from(c);
}
public int getCount() {
return count;
}
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();
String id = null;
TextView txt_itemName = null;
if (convertView == null) {
convertView = l_Inflater.inflate(R.layout.menu, null);
}
txt_itemName = (TextView) convertView.findViewById(R.id.textView1);
convertView.findViewById(R.id.imageView1);
music_column_index = musiccursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
musiccursor.moveToPosition(position);
id = musiccursor.getString(music_column_index);
txt_itemName.setText(id);
return convertView;
}
}

Related

Method call expected in Android BaseAdapter

I'm trying to extend a BaseAdapter to make my custom listview. But it says:
method call expected` in the getCount() method.
I know it's an Array, so how do I fetch it? I'm basically a nube in this field. Here is my code I have tried to apply:
public class customAdapter extends BaseAdapter implements View.OnClickListener {
private Context context;
private String[] restaurant;
private String[] address;
private String[] time;
private static LayoutInflater layoutInflater = null;
public Resources res;
int image[];
ListModel tempvalues = null;
int i=0;
public customAdapter(MainActivity mainActivity, String[] rest, String[] add,String[] tim,int[] img){
restaurant = rest;
context=mainActivity;
address= add;
time = tim;
image = img;
layoutInflater = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return restaurant.length(); // Method call expected.
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder{
TextView resname;
TextView resadd;
TextView restim;
ImageView imageView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = new Holder();
View rowview;
rowview = layoutInflater.inflate(R.layout.custom_list_view_for_restaurant_names,null);
holder.resname = (TextView)rowview.findViewById(R.id.resnameTextView);
holder.resadd = (TextView)rowview.findViewById(R.id.address_textview);
holder.restim = (TextView)rowview.findViewById(R.id.time_textview);
holder.imageView = (ImageView)rowview.findViewById(R.id.imageView);
holder.resname.setText(restaurant[position]);
holder.resadd.setText(address[position]);
holder.restim.setText(time[position]);
holder.imageView.setImageResource(image[position]);
rowview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return rowview;
}
#Override
public void onClick(View v) {
}
}
Change
return restaurant.length();
to
return restaurant.length;
restaurant is a Array not a List
And one more thing I would like to suggest you,
Do not pass these arrays separately, because that will logically break the code, if some array size becomes less than the restaurant array.
I suggest you to use a model,
eg:
public class Event {
private String restaurant;
private String address;
private String time;
private int image;
//getters and setters
}
and pass a list of Event s
like below,
private List<Event> events;
public customAdapter(MainActivity mainActivity, List<Event> events){
this.events = events;
layoutInflater = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return events.size(); // Method call expected.
}
#Override
public Object getItem(int position) {
return events.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
and access that,
Event event = events.get(position);
holder.resname.setText(event.getResturant());
holder.resadd.setText(event.getAddress());
holder.restim.setText(event.getTime());
holder.imageView.setImageResource(event.getImage());
And also,
You should not inflate the ListView Elements all the time you should reuse the already inflated elements.
View view = convertView;
if (view == null) {
// if it's not recycled, initialize some attributes
LayoutInflater inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.custom_list_view_for_restaurant_names,null);
}

Custom ListView Adapters for multiple TextViews

I am working on an app with multiple TextViews in a ListView, but I seem to have encountered a problem. The list does not appear to get modified.
I'm attachig my code now
public class MainActivity extends ActionBarActivity {
private List<CustomItem> myItem = new ArrayList<>();
ListView listView;
EditText edit;
Button insert;
String getText;
StringTokenizer st;
private String text1,text2;
List<CustomItem> customItem = new ArrayList<CustomItem>();
ArrayAdapter<CustomItem> adapter_List;
CompleteAdapter completeAdapter;
CustomItem obj;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.editText);
insert = (Button)findViewById(R.id.addBtn);
populate();
listView = (ListView) findViewById(R.id.listView);
completeAdapter = new CompleteAdapter(customItem, this);
listView.setAdapter(completeAdapter);
}
private void populate() {
customItem.add(new CustomItem("Testing","Application"));
}
public void addToList(View view) {
getText = edit.getText().toString();
st = new StringTokenizer(getText," ");
text1 = st.nextToken().toString();
text2 = st.nextToken().toString();
MainActivity.this.customItem.add(new CustomItem(text1,text2));
MainActivity.this.completeAdapter.notifyDataSetChanged();
}
/*
private class MyListAdapter extends ArrayAdapter<CustomItem> {
private MyListAdapter() {
super(MainActivity.this, R.layout.item_row,myItem);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(itemView== null){
itemView = getLayoutInflater().inflate(R.layout.item_row,parent,false);
}
CustomItem customItem = myItem.get(position);
TextView t1 = (TextView) itemView.findViewById(R.id.text1);
TextView t2 = (TextView) itemView.findViewById(R.id.text2);
t1.setText(customItem.getName());
t2.setText(customItem.getAddress());
return itemView;
}
}*/
}
this is my adapter class
class CompleteAdapter extends ArrayAdapter<CustomItem>{
private List<CustomItem> items;
private Context context;
CompleteAdapter(List<CustomItem> items, Context context) {
super (context,R.layout.item_row,items);
this.items = items;
this.context = context;
}
#Override
public int getCount() {
return 0;
}
#Override
public CustomItem getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v= convertView;
Holder holder = new Holder();
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.item_row, null);
TextView name_text = (TextView)v.findViewById(R.id.name);
TextView address_text = (TextView)v.findViewById(R.id.address);
holder.nameView = name_text;
holder.addView = address_text;
v.setTag(holder);
}
else
holder = (Holder)v.getTag();
CustomItem custom = items.get(position);
holder.nameView.setText(custom.getName());
holder.addView.setText(custom.getAddress());
return v;
}
private class Holder {
public TextView nameView;
public TextView addView;
}
}
This is my CustomIte.java
class CustomItem{
private String name;
private String address;
CustomItem(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}}
As you can see I've tried with 2 adapters with the same result. There is data contained in the Strings being passed, so I think the problem is with the adapter. (The ids of all the components are perfect) What changes should I make?
Should change in your Adapter
#Override
public int getCount() {
return 0;
}
#Override
public CustomItem getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
to
#Override
public int getCount() {
return items.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public CustomItem getItem(int position) {
return items.get(position);
}
The problem is in your adapter which return a null view (v)
#Override
public int getCount() {
return items.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public CustomItem getItem(int position) {
return items.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if(convertView == null){
convertView =LayoutInflater.from(context).inflate(R.layout.item_row, null);
TextView name_text = (TextView)v.findViewById(R.id.name);
TextView address_text = (TextView)v.findViewById(R.id.address);
holder = new Holder();
holder.nameView = name_text;
holder.addView = address_text;
v.setTag(holder);
}
else
holder = (Holder)v.getTag();
CustomItem custom = items.get(position);
holder.nameView.setText(custom.getName());
holder.addView.setText(custom.getAddress());
return convertView ;
}
Hop it helps ;)

Android : How do I return the item as a char not an object from a custom gridview

I am developing a hangman game for android, I am struggling with setting the gameplay rules for the onclick listener as gridview.getItem returns an object not a char value.
custom grid view
public class CustomGridAdapter extends BaseAdapter {
private Context context;
private String[] items;
LayoutInflater inflater;
public CustomGridAdapter(Context context, String[] items) {
this.context = context;
this.items = items;
inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.cell, null);
}
Button button = (Button) convertView.findViewById(R.id.grid_item);
// text is set on button through a string array
button.setText(items[position]);
return convertView;
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int position) {
return items[position];
}
#Override
public long getItemId(int position) {
return position;
}
}
You should modify your code as here
#Override
public String getItem(int position) {
return items[position];
}
You can still use the BaseAdapter by changing the getItem as
#Override
public String getItem(int position) {
return items[position];
}
Or you can use an ArrayAdapter
If your items are strings then why not do:
#Override
public String getItem(int position) {
return items[position];
}
I might be wrong with this I'm new at android programming

Gridview Taking Limited Values to Display

Am having a custom Gridview to display a list of operators with their icon and names of the provider.my problem is the Gridview displaying only Limited providers (12 only).But am having more than 16 values to display.the Remaining Values is getting Repeated in Gridview while Scrolling GridView.
my source code is Here
public class ImageAdapter extends BaseAdapter {
public int getCount() {
return providerlist1.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
View v;
ImageView imageView;
if (convertView == null) {
LayoutInflater layoutInflater = getLayoutInflater();
v = layoutInflater.inflate(R.layout.icon_with_text, null);
TextView txt = (TextView) v.findViewById(R.id.icon_text);
txt.invalidate();
txt.setTypeface(localTypeface1);
Collections.sort(providerlist1);
Log.v("COLLECTIONS", ""+providerlist1);
txt.setText("" + providerlist1.toArray()[position]);
String string = (String) txt.getText();
icon = string.toLowerCase();
System.out.println(icon);
int resid = getResources().getIdentifier("" + icon, "drawable",
"com.digient.yeldi.app");
imageView = (ImageView) v.findViewById(R.id.icon_image);
imageView.setImageResource(resid);
} else {
v = convertView;
}
return v;
}
}
providerlist1 is an arraylist in which am having more than 16 operators values.
Use Below Code for that, may be it will help you.
public class ImageAdapter extends BaseAdapter {
LayoutInflater layoutInflater;
Context ctx;
public ImageAdapter(Context context) {
// TODO Auto-generated constructor stub
layoutInflater=LayoutInflater.from(context);
this.ctx=context;
}
public int getCount() {
return providerlist1.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
View v;
ImageView imageView;
if (convertView == null) {
v = layoutInflater.inflate(R.layout.icon_with_text, null);
} else {
v = convertView;
}
TextView txt = (TextView) v.findViewById(R.id.icon_text);
txt.invalidate();
txt.setTypeface(localTypeface1);
Collections.sort(providerlist1);
Log.v("COLLECTIONS", ""+providerlist1);
txt.setText("" + providerlist1.toArray()[position]);
String string = (String) txt.getText();
icon = string.toLowerCase();
System.out.println(icon);
int resid = getResources().getIdentifier("" + icon, "drawable", "com.digient.yeldi.app");
imageView = (ImageView) v.findViewById(R.id.icon_image);
imageView.setImageResource(resid);
return v;
}
}

Android - ListView with different heights in each row / getView()

I want to build a dynamic ListView (like a chat list with different layouts/bubbles).
My problem is, that each row has an individual height. My code below works,
but every time I scroll down or receive a new message,
the row with a different height gets heigher.
private class dialogAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public dialogAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public boolean hasStableIds() {
return true;
}
public int getCount() {
return dialog.size();
}
public int getViewTypeCount() {
return 999999;
}
public Object getItem(int position) {
return dialog.get(position);
}
public int getItemViewType(int position) {
return position;
}
public String getType(int position) {
return dialogType.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Log.w("DRAGII", "POS: "+position);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.bubble, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.parser = new URLImageParser(holder.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position <= dialogCache.size())
dialogCache.add(position, Html.fromHtml((String)getItem(position),
holder.parser, null));
holder.text.setText(dialogCache.get(position));
holder.type = getType(position);
int bubble = R.drawable.bubble;
if (holder.type.equals("R")) bubble = R.drawable.bubble_right;
else if (holder.type.equals("L")) bubble = R.drawable.bubble_left;
holder.text.setBackgroundResource(bubble);
return convertView;
}
class ViewHolder {
TextView text;
String type = "B";
URLImageParser parser;
}
}
What should I do?
Solved this problem by using TableLayout instead of ListView.
if u are adding tableRow programmatically to tableLayout, you will have performance issues. Think it again and find a way by using listView

Categories

Resources