I´ve a problem in my Android Project. It´s a music track player, which shows each track in a ListFragment. Every item has got a Bitmap, where an oscilloscope is drawn on the bitmaps canvas. The items in the Listfragment are refreshed periodically. This is done via notifyDataSetChanged();
I also want to mute one track when I click on the item, but the onItemClick event doesn´t get fired every time. Only sometimes. Can anyone explain this to me? What am I doing wrong here? It works perfect without notifyDataSetChanged(), but then the items are not refreshed.
Thanks!
This is the full code:
Mainactivity:
package de.sma.stackoverflow;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MyListFragment
package de.sma.stackoverflow;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.app.ListFragment;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
public class MyListFragment extends ListFragment implements OnItemClickListener
{
ListViewAdapter adapter;
private List<ListViewItem> rowItems;
private Handler sampleUpdateHandler = new Handler();
Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
boolean bMuted = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_list_layout, null, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
paintText.setColor(Color.WHITE);
paintText.setStyle(Paint.Style.FILL);
rowItems = new ArrayList<ListViewItem>();
rowItems.add(new ListViewItem("Android"));
rowItems.add(new ListViewItem("iOS"));
rowItems.add(new ListViewItem("Symbian"));
rowItems.add(new ListViewItem("Blackberry"));
rowItems.add(new ListViewItem("Windows Phone"));
rowItems.add(new ListViewItem("Galaxy Nexus"));
rowItems.add(new ListViewItem("Offline"));
adapter = new ListViewAdapter(getActivity(), rowItems);
setListAdapter(adapter);
getListView().setOnItemClickListener(this);
StartThread();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Log.d("WhyDoesntThisWork", "onListItemClick");
bMuted = !bMuted;
}
private void StartThread()
{
new Thread(new Runnable()
{
Random rand = new Random();
public int randInt(int min, int max)
{
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
@Override
public void run()
{
while (true)
{
try
{
Thread.sleep(10);
sampleUpdateHandler.post(new Runnable()
{
@Override
public void run()
{
Canvas myCanvas = rowItems.get(0).getCanvas();
if (bMuted)
myCanvas.drawColor(0xFFFF0000);
else
myCanvas.drawColor(0xFF000020);
for (int i = 0; i < myCanvas.getWidth(); i++)
myCanvas.drawLine(i, randInt(0, 50), i + 1, randInt(0, 50), paintText);
adapter.notifyDataSetChanged();
}
});
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start();
}
}
ListViewItem:
package de.sma.stackoverflow;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.widget.ImageView;
public class ListViewItem
{
private String title;
private Bitmap mBitmap;
private Canvas mCanvas;
private ImageView mImageView;
public ListViewItem(String title)
{
this.title = title;
mBitmap = Bitmap.createBitmap(100, 50, Bitmap.Config.RGB_565);
mCanvas = new Canvas(mBitmap);
mCanvas.drawColor(0xFF2020FF);
}
public Canvas getCanvas()
{
return mCanvas;
}
public String getTitle()
{
return title;
}
public Bitmap getBitmap()
{
return mBitmap;
}
public void setImageView(ImageView imageView)
{
this.mImageView = imageView;
}
}
ListViewAdapter:
package de.sma.stackoverflow;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class ListViewAdapter extends BaseAdapter
{
Context context;
List<ListViewItem> rowItem;
ListViewAdapter(Context context, List<ListViewItem> rowItem)
{
this.context = context;
this.rowItem = rowItem;
}
@Override
public int getCount()
{
return rowItem.size();
}
@Override
public Object getItem(int position)
{
return rowItem.get(position);
}
@Override
public long getItemId(int position)
{
return rowItem.indexOf(getItem(position));
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
ListViewItem row_pos = rowItem.get(position);
// setting the image resource and title
txtTitle.setText(row_pos.getTitle());
ImageView imageView = (ImageView) convertView.findViewById(R.id.icon);
imageView.setImageBitmap(row_pos.getBitmap());
row_pos.setImageView(imageView);
return convertView;
}
}
Main Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="@+id/fragment1"
android:name="de.sma.stackoverflow.MyListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
List layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
<TextView
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TextView>
</LinearLayout>
List item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="5dp" >
<ImageView
android:id="@+id/icon"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:contentDescription="imgdesc"
android:layout_alignParentTop="true"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_toRightOf="@id/icon"
android:gravity="center_vertical"
android:textColor="#000000"
android:textSize="20sp"
android:text="test"/>
</RelativeLayout>
Everything is fine in your codes, Main reason of not being an item clicked is because of you have used
while (true)
Statement which is always true. The item which is currently being processed inside the thread will not be clicked and the items which are currently excluded from thread is being clickable. How ever you have to make your thread not to run inside loop. So that what you can do is either remove yourwhile(true)
statement, OR replace that withif(true)
.