I have a recyclerview displaying a simple list of items. On long pressing a particular item, a piece of audio associated with this item (stored in the assets folder) is played. On releasing, the audio is paused, and can be returned to at the paused point by long pressing. To that end, I implemented an onTouchListener in the ViewHolder of the RecyclerViews Adapter and created an interface that I call in onBindViewHolder. It works but when I scroll through the items the audio plays automatically and loops endlessly. I can still long press an item and hear its audio playing on top of the automatically looping audio.
I'm not sure where exactly the problem is. I'm not sure if it relates to the way items are recycled in RecyclerView, given it's only something thats an issue when I scroll? I tried to add an onItemTouchListener in the the corresponding fragment and do the work over there but had the same issue.
Or maybe the problem is in how I've set up my onTouchListener and interface? I'm not sure I fully understand what should be happening in onInterceptTouchEvent.
Or does the issue maybe lie in how I've set up my mediaplayer in the onTouchEvent?
public class ClapsAdapter extends RecyclerView.Adapter<ClapsAdapter.ViewHolder> {
List<Clap> mItems;
private Context context;
ItemTouchListener itlistener;
GestureDetector mGestureDetector;
public interface ItemTouchListener {
boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e, List<Clap> list);
void onTouchEvent(List<Clap> list, View view, int position, MotionEvent me);
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
}
#Override
public long getItemId(int position) {
return position;
}
public ClapsAdapter(Context mContext, List<Clap> myClap) {
super();
this.mItems = myClap;
this.context = mContext;
setHasStableIds(true);
mItems = new ArrayList<Clap>();
Clap mClaps = new Clap();
mClaps.setCName("Hearty Clap");
mClaps.setImageId(R.drawable.clapping1);
mClaps.setAudio("applause-01.mp3");
mItems.add(mClaps);
mClaps = new Clap();
mClaps.setCName("Business Clap");
mClaps.setImageId(R.drawable.clapping2);
mClaps.setAudio("fake_applause.mp3");
mItems.add(mClaps);
mClaps = new Clap();
mClaps.setCName("Green Clap");
mClaps.setImageId(R.drawable.clap3);
mClaps.setAudio("laugh_and_applause.mp3");
mItems.add(mClaps);
mClaps = new Clap();
mClaps.setCName("Slow Clap");
mClaps.setImageId(R.mipmap.slow_clap);
mClaps.setAudio("fake_applause.mp3");
mItems.add(mClaps);
mClaps = new Clap();
mClaps.setCName("Emoji Clap");
mClaps.setImageId(R.mipmap.clap_emoji);
mClaps.setAudio("light_applause.mp3");
mItems.add(mClaps);
mClaps = new Clap();
mClaps.setCName("Slow Clap");
mClaps.setImageId(R.mipmap.slow_clap);
mClaps.setAudio("laughter-1.wav");
mItems.add(mClaps);
mClaps = new Clap();
mClaps.setCName("Emoji Clap");
mClaps.setImageId(R.mipmap.clap_emoji);
mClaps.setAudio("laughter-2.mp3");
mItems.add(mClaps);
// this.itlistener = itl;
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnTouchListener{
public TextView title;
public ImageView imageView;
private ItemTouchListener touchListener;
final MediaPlayer mp = new MediaPlayer();
private Context mContext;
List<Clap> mItems;
public ViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.icon);
title = (TextView) itemView.findViewById(R.id.description);
itemView.setTag(itemView);
itemView.setClickable(true);
itemView.setOnTouchListener(this);
}
public void setTouchListener (ItemTouchListener itemTouchListener){
this.touchListener = itemTouchListener;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (touchListener != null) {
touchListener.onTouchEvent(mItems, v, getAdapterPosition(), event);
} return true;
}
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
//Inflate the layout, initialize the View Holder
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_clap, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Clap clap = mItems.get(position);
holder.title.setText(mItems.get(position).getCName());
holder.imageView.setImageResource(mItems.get(position).getImageId());
final MediaPlayer mp = new MediaPlayer();
holder.setTouchListener(new ItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e, List<Clap> list) {
View childView = rv.findChildViewUnder(e.getX(), e.getY());
if (childView != null && this != null && mGestureDetector.onTouchEvent(e)) {
this.onTouchEvent(list, rv,rv.getChildAdapterPosition(childView), e);
}
return true;
}
#Override
public void onTouchEvent(List<Clap> list, View view, int position, MotionEvent me) {
// Toast.makeText(context, "TOUCH ME!!!",
// Toast.LENGTH_SHORT).show();
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN: {
if (mp.isPlaying()) {
mp.stop();
mp.release();
}
try {
mp.reset();
AssetFileDescriptor afd;
afd = view.getContext().getAssets().openFd(mItems.get(position).getAudio());
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mp.setLooping(true);
mp.start();
}
break;
case MotionEvent.ACTION_UP: {
mp.pause();
Toast.makeText(context, mItems.get(position).getCName(),
Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
}
#Override
public int getItemCount() {
//returns the number of elements the RecyclerView will display
//return items.size();
return (null != mItems ? mItems.size() : 0);
}
public void insert(int position, Clap clap) {
mItems.add(position, clap);
notifyItemInserted(position);
}
public void remove(Clap clap) {
int position = mItems.indexOf(clap);
mItems.remove(position);
notifyItemRemoved(position);
}
Any help on the matter would be greatly appreciated. I feel like I've spent more time stuck on this than I should!
you should read about managing touch events in view group
http://developer.android.com/training/gestures/viewgroup.html
You can attach GestureDetector to your onTouchEvent() and then write your logic in onLongPress().
GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
public void onLongPress(MotionEvent e) {
//do something here
}
});
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
};
Related
I have a Listview, in which every row has play button. If i clicked on First Play Button it changes to pause but if i pressed second row play button,then first will remain in pause state but i want that if any of button is pressed then the previous button back to its play state and the clicked one changes to pause.
Code is below.
public class RingsAdapter extends BaseAdapter {
private Context context;
private ArrayList<Ringsinfo> data;
private SqlLiteDbHelper db;
private MediaPlayer mediaPlayer;
int pause_button_position = -1;
public RingsAdapter(Context mContext) {
data = new ArrayList<Ringsinfo>();
context = mContext;
initDatabase(context);
mediaPlayer = new MediaPlayer();
}
private void initDatabase(Context c) {
db = new SqlLiteDbHelper(c);
try {
db.CopyDataBaseFromAsset();
db.openDataBase();
} catch (IOException e) {
e.printStackTrace();
}
}
public void AddAll(ArrayList<Ringsinfo> listperson) {
data.clear();
data.addAll(listperson);
notifyDataSetChanged();
}
#Override
public int getCount() {
return this.data.size();
}
#Override
public Object getItem(int position) {
return (Ringsinfo) this.data.get(position);
}
#Override
public long getItemId(int position) {
return (long) position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
HolderView mHolderView;
if (convertView == null) {
mHolderView = new HolderView();
convertView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.row_ringtone_list, parent, false);
mHolderView.btnPlay = (Button) convertView.findViewById(R.id.btnPlay);
mHolderView.btnSetting = (Button) convertView.findViewById(R.id.btnSetting);
mHolderView.tvRingName = (TextView) convertView.findViewById(R.id.tvRingName);
convertView.setTag(mHolderView);
} else {
mHolderView = (HolderView) convertView.getTag();
}
mHolderView.tvRingName.setText(((Ringsinfo) this.data.get(position)).name);
mHolderView.btnSetting.setOnClickListener(new RingDetails(position));
mHolderView.btnPlay.setOnClickListener(new playRingtone(position));
if (position != pause_button_position)
mHolderView.btnPlay.setBackgroundResource(R.mipmap.play);
return convertView;
}
class RingDetails implements View.OnClickListener {
final int val$position;
RingDetails(int i) {
this.val$position = i;
}
public void onClick(View view) {
Intent intent = new Intent(context, RingDetailActivity.class);
intent.putExtra("calls", ((Ringsinfo) data.get(this.val$position)).content);
intent.putExtra("heading", ((Ringsinfo) data.get(this.val$position)).name);
context.startActivity(intent);
}
}
class playRingtone implements View.OnClickListener {
int val$position;
playRingtone(int i) {
val$position = i;
}
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
view.setBackgroundResource(R.mipmap.play);
} else {
view.setBackgroundResource(R.mipmap.pause);
pause_button_position = val$position;
mediaPlayer.start();
}
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(context, new Builder().scheme("android.resource").authority(context.getPackageName()).appendPath(String.valueOf(context.getResources().getIdentifier(((Ringsinfo) data.get(val$position)).content + BuildConfig.FLAVOR, "raw", context.getPackageName()))).build());
mediaPlayer.start();
}
}
private class HolderView {
private Button btnPlay, btnSetting;
private TextView tvRingName;
}
public void Stop() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.reset();
mediaPlayer.stop();
mediaPlayer.release();
}
}}
You need to write else condition in your Adapter where you change your background for ImageView
if (position != pause_button_position)
mHolderView.btnPlay.setBackgroundResource(R.mipmap.play);
else
mHolderView.btnPlay.setBackgroundResource(R.mipmap.pause);
Also, It would be good if you manage one Boolean list in Adapter to manager your play pause button.
Like your Boolean list is same size of your ArrayList. once user click on 1st play button then you need to set true at 1st position of Boolean List and rest of are false. Same way if user click on 2nd play button then set true at 2nd position of your Boolean List and keep rest of false and notify your Adapter.
and your play pause button background is now based on Boolean List.
MyAdapter:
public class voice_player_listview_adapter extends ArrayAdapter<String> {
public ArrayList<String> Duration=null;
public ArrayList<String> voice_id=null;
private Activity context;
public voice_player_listview_adapter(Activity context,ArrayList<String> voice_id,ArrayList<String> Duration) {
super(context, R.layout.voice_player_listview,sender);
// TODO Auto-generated constructor stub
this.context=context;
this.voice_id=voice_id;
this.Duration=Duration;
}
public View getView(final int position, final View convertView, ViewGroup parent) {
View rowView=convertView;
final viewHolder holder; //viewHolder already created in some where
if (rowView==null)
{
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.voice_player_listview, parent, false);
holder= new viewHolder();
holder.icon=(ImageView) rowView.findViewById(R.id.download_play_icon);
holder.voice_duration=(TextView) rowView.findViewById(R.id.voiceDuration);
holder.voice_player_seekbar=(SeekBar) rowView.findViewById(R.id.voice_player_seekbar);
rowView.setTag(holder);
}
else
{
holder= (viewHolder) convertView.getTag();
}
holder.voice_duration.setText("00:"+this.Duration.get(position));
holder.icon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new voicePlayer(voice_id.get(position),holder);
}
});
...
VoicePlayer:
class voicePlayer {
MediaPlayer mediaPlayer;
SeekBar seekbar;
TextView voice_duration;
ImageView icon;
viewHolder rowView;
final Handler handler = new Handler();
public void getViews()
{
this.seekbar=rowView.voice_player_seekbar;
this.voice_duration=rowView.voice_duration;
this.icon=rowView.icon;
}
public voicePlayer(String voice_id,WavesAPI.viewHolder holder) {
this.rowView=holder;
getViews();
try {
mediaPlayer=new MediaPlayer();
FileInputStream fis = new FileInputStream(Environment.getExternalStorageDirectory()...);
mediaPlayer.setDataSource(fis.getFD());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepare();
mediaPlayer.start();
this.icon.setImageResource(R.drawable.pause);
this.updateSeekbar();
this.seekbar_listener();
} catch (IOException e) {
}
} catch (IOException e) {
}
}
}
private void updateSeekbar()
{
final Runnable runnable = new Runnable() {
public void run() {
int position= // calculating the position of the mediaPlayer for updating the seekbar
seekbar.setProgress(position);
handler.postDelayed(this, 50);
voice_duration.setText("00:"+((WavesAPI.player_data.mediaPlayer.getDuration()/1000)-(WavesAPI.player_data.mediaPlayer.getCurrentPosition()/1000)));
}
};
handler.post(runnable);
}
public void seekbar_listener()
{
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser)
{
int player_position=// calc new postion of the mediaPlayer
mediaPlayer.seekTo(player_position);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
The problem: when i click on play icon on the row of listview the music plays and the seekbar gets updated correctly as long as i don't scroll. But, Since the screen/listview fit only 3 items, when i scroll down, every 4 row, i see the new row seekbar is updating with the same progress of the old row i played and scrolled off. i think the convertView generates the same old instance view that once created and passed to the voicePlayer. once i didn't consider convertView and for every getView i create new rowView by inflater.inflate , the duplicating instance issue was resolved but when i scroll off a item and re-scroll back to the item, updating was stopped.
The problem solved. i used ScrollView instead of ListView
I have a list in which each element on a player. When I click on "start" and a song starts playing strip seekbar starts moving. when click on the "stop" the song stops playing and the strip stops. But if while moving the strip I scroll list and it goes off the screen, it starts to move another strip that is on the same position in the visible area of the screen.
public class RecordAdapter extends BaseAdapter {
private MediaPlayer mediaPlayer;
private LayoutInflater inflater;
private ArrayList<RecordBean> recordBeans;
private final Handler handler = new Handler();
private Context ctx;
private int global_position;
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
view = inflater.inflate(R.layout.recorditem, parent, false);
holder = new ViewHolder();
holder.date = (TextView) view.findViewById(R.id.recordate);
holder.seekBar = (SeekBar) view.findViewById(R.id.seekBar);
holder.start = (Button) view.findViewById(R.id.btnStart);
holder.stop = (Button) view.findViewById(R.id.btnStop);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.date.setText(" " + recordBeans.get(position).getDate());
holder.start.setTag(position);
holder.stop.setTag(position);
holder.seekBar.setTag(position);
holder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(final SeekBar seekBar, final int i, boolean b) {
if (b && (Integer)seekBar.getTag()==global_position) {
mediaPlayer.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
holder.start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMP();
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(recordBeans.get((Integer) v.getTag()).getFile());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
global_position = position;
holder.start.setTextColor(Color.RED);
holder.seekBar.setMax(mediaPlayer.getDuration());
startPlayProgressUpdater(holder.seekBar,holder.start);
}
});
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
if (mediaPlayer == null) {
return;
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.d("LOG_TAG", "onCompletion");
holder.start.setTextColor(Color.WHITE);
}
});
}
});
holder.stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer == null)
return;
if ((Integer) v.getTag() == global_position) {
mediaPlayer.stop();
}
}
});
return view;
}
private void releaseMP() {
if (mediaPlayer != null) {
try {
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static class ViewHolder {
TextView date;
SeekBar seekBar;
Button start;
Button stop;
}
public void startPlayProgressUpdater(final SeekBar seek, final Button start) {
seek.setProgress(mediaPlayer.getCurrentPosition());
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater(seek,start);
}
};
handler.postDelayed(notification, 1000);
} else {
mediaPlayer.pause();
seek.setProgress(0);
}
}
}
EDIT:
I added geter and seter in recordBean
public int getSeekPos() {
return SeekPos;
}
public void setSeekPos(int seekPos) {
SeekPos = seekPos;
}
and
holder.seekBar.setProgress(recordBeans.get(position).getSeekPos());
holder.date.setText(" " + recordBeans.get(position).getDate());
and
#Override
public void onProgressChanged(final SeekBar seekBar, final int i, boolean b) {
if (b && (Integer)seekBar.getTag()==global_position) {
// mediaPlayer.seekTo(i);
recordBeans.get(position).setSeekPos(i);
}
}
but I think it left something extra in my code
The list item is being recycled when it leaves the screen.
You could try to call this in getView:
holder.seekBar.clearFocus();
This is a tricky process, but you can do this in the following way, as I have seen that you have created a List of RecordBean class. So what you can do is you have to create a Getter Setter in RecordBean for storing the position of you SeekBar like:
public void setSeekPos(int pos) {
this.pos = pos;
}
public int getSeekPos() {
return pos;
}
In your adapter below the line
holder.date.setText(" " + recordBeans.get(position).getDate());
set the progress of seekBar like this: holder.seekBar.setProgress(recordBeans.get(position).getSeekPos());
and inside the onProgressChanged add the following line recordBeans.get(position).setSeekPos(i);
This will resolve your issue.
Please let me know if it's working or not.
Thanks
I have an Vertical listview i want listview should be closed. For example if the last item is reached in Listview then show the first item below the last item. It means item should be in circular format. And if i scroll from first item it should show last item before first item. I want scrolling for both side.
public class MainActivity extends Activity {
ListView list;
long startTime;
long endTime;
List<String> mList = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.list);
downloadDetails();
String str;
for (int i = 0; i < 10; i++) {
str = new String("Data --- " + i);
mList.add(str);
}
CircularAdapter adapter = new CircularAdapter(this, 0, mList);
list.setAdapter(adapter);
final YourRunnable runy = new YourRunnable();
list.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startTime = (new Date()).getTime();
runy.onPause();// pausing thread actually pauses scrolling
}
if (event.getAction() == MotionEvent.ACTION_UP) {
endTime = (new Date()).getTime();
if ((endTime - startTime) <= 100) {// 100 mill second limit
// for click
// Log.i("ITEM CLICK() ", "item : ");
}
runy.onResume(); // resume scrolling
}
return false;
}
});
new Thread(runy).start();
}
class YourRunnable implements Runnable {
private Object mPauseLock;
private boolean mPaused;
private boolean mFinished;
public YourRunnable() {
mPauseLock = new Object();
mPaused = false;
mFinished = false;
}
#SuppressLint("NewApi")
public void run() {
while (!mFinished) {
// for loop is not infinite but enough as Integer.MAX_VALUE
for (int index = 0; index < list.getAdapter().getCount(); index++) {
list.smoothScrollToPositionFromTop(list.getLastVisiblePosition() + 1, 0, 10000);
try {
// it helps scrolling to stay smooth as possible (by
// experiment)
Thread.sleep(3000);
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();// putting thread in wait
// list of mPauseLock
// object
} catch (InterruptedException e) {
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// to pause list
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
// resume thread
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();// notify all object that are waiting on
// the wait list of mPauseLock object
}
}
}
private class CircularAdapter extends ArrayAdapter {
List<String> mlist;
Context mContext;
LayoutInflater inflater;
public final int HALF_MAX_VALUE = Integer.MAX_VALUE / 2;
public final int MIDDLE;
#SuppressWarnings("unchecked")
public CircularAdapter(Context ctx, int resId, List<String> objects) {
super(ctx, resId, objects);
mContext = ctx;
mlist = objects;
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % mlist.size();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
int relativePos = position % mlist.size();
Log.i("RELATIVE : ", " POS:" + relativePos);
return mlist.get(relativePos);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item, parent, false);
holder.name = (TextView) convertView.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String model = getItem(position);
holder.name.setText(model);
convertView.setOnClickListener(new ListenerT(model) {
#Override
public void onClick(View v) {
Log.i("CLICK", "ITEM---" + name);
}
});
return convertView;
}
}
// use your own listener to pass parameter
private class ListenerT implements OnClickListener {
String name;
public ListenerT(String nm) {
name = nm;
}
#Override
public void onClick(View v) {
}
}
private class ViewHolder {
TextView name;
}
}
i have small issues in event handling , i have List view custom adapter data , each row having date , title , price . when i click on row i need to display details page but when i long press on price , date or title i need to sort the list view. i need to use gesture for on Long Press. please refer below code what i have tried.
Custom Adapter View
public EventAdapterView(Context context, List<EventUtil> eventList) {
this.mContext = context;
this.mEventUtil = eventList;
mLayoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new DrawableManager();
}
#SuppressLint("DefaultLocale")
#SuppressWarnings("deprecation")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
mView = convertView;
EventUtil eventUtil = mEventUtil.get(position);
mView = mLayoutInflater.inflate(R.layout.row_event_adapter, null);
TextView eventTitleView = (TextView) mView
.findViewById(R.id.list_view_event_title);
TextView eventDescView = (TextView) mView
.findViewById(R.id.list_view_event_location);
TextView eventDateView = (TextView) mView
.findViewById(R.id.list_view_event_price);
// final MyGestureDetector myGestureDetector= new MyGestureDetector();
// new ImageFeach().execute(mEventUtil.getEvent_Image_Url());
eventTitleView.setText(eventUtil.getEvent_Title());
// event title sorting
eventTitleView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
new MyGestureDetector() {
public void onLongPress(MotionEvent event1) {
//if (event1.getAction() == MotionEvent.ACTION_DOWN) {
Collections.sort(mEventUtil,
new Comparator<EventUtil>() {
#Override
public int compare(EventUtil obje1,
EventUtil obje2) {
return obje1
.getEvent_Title()
.compareTo(
obje2.getEvent_Title());
}
});
notifyDataSetChanged();
//}
};
}.onLongPress(event);
return true;
}
});
// event location sorting
eventDescView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
new MyGestureDetector() {
public void onLongPress(MotionEvent event1) {
//if (event1.getAction() == MotionEvent.ACTION_DOWN) {
Collections.sort(mEventUtil,
new Comparator<EventUtil>() {
#Override
public int compare(EventUtil event1,
EventUtil event2) {
return event1
.getEvent_location()
.compareTo(
event2.getEvent_location());
}
});
notifyDataSetChanged();
//}
};
}.onLongPress(event);
return true;
}
});
// event price sorting
eventDateView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
new MyGestureDetector() {
public void onLongPress(MotionEvent event1) {
// if (event1.getAction() == MotionEvent.ACTION_DOWN) {
Collections.sort(mEventUtil,
new Comparator<EventUtil>() {
#Override
public int compare(EventUtil event1,
EventUtil event2) {
return event1
.getEvent_Price()
.compareTo(
event2.getEvent_Price());
}
});
notifyDataSetChanged();
//}
};
}.onLongPress(event);
return true;
}
});
// event date sorting
ImageView dateImageView = (ImageView) mView
.findViewById(R.id.list_view_event_date);
dateImageView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
new MyGestureDetector() {
public void onLongPress(MotionEvent event1) {
//if (event1.getAction() == MotionEvent.ACTION_DOWN) {
Collections.sort(mEventUtil,
new Comparator<EventUtil>() {
#Override
public int compare(EventUtil event1,
EventUtil event2) {
return event2
.getEvent_Date()
.compareTo(
event1.getEvent_Date());
}
});
notifyDataSetChanged();
//}
};
}.onLongPress(event);
return true;
}
});
MyGestureDetector Class
public class MyGestureDetector extends SimpleOnGestureListener {
#Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
}
}
Help Me.. Thanks
I think, there's no need to use SimpleOnGestureListener.
In your Custom Adapter View:
First,
eventTitleView.setFocusable(false);
eventTitleView.setFocusableInTouchMode(false);
eventTitleView.setLongClickable(true);
eventDescView.setFocusable(false);
eventDescView.setFocusableInTouchMode(false);
eventDescView.setLongClickable(true);
eventDateView.setFocusable(false);
eventDateView.setFocusableInTouchMode(false);
eventDateView.setLongClickable(true);
Then,
just set setOnLongClickListener (View.OnLongClickListener l) on eventTitleView, eventDescView and eventDateView as,
eventTitleView.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//do your sorting stuff here
}
});
eventDescView.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//do your sorting stuff here
}
});
eventDateView.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//do your sorting stuff here
}
});
Hope this helps you.
Why do you need to override onlongpress?
You know this function is available by default right?
just put the price , date or title on the same Layout and give each one OnLongPressListener with the action you want..:
EXAMPLE:
http://www.mikeplate.com/2010/01/21/show-a-context-menu-for-long-clicks-in-an-android-listview/
I have done this thro onLongClickListener. It's easy using this interface . You need to do
Class YourClass implements onLongClickListener{
public boolean onLongClick(View arg0){
// Event generated when user have long pressed the screen
return false; // If you do not want the event to keep occuring again and again
}
ListView.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// YOUR SORTING CODE HERE
return false;
}
});