I'm scrolling two listview by passing touch event to both of them.
OnTouchListener touchListener = new OnTouchListener() {
boolean dispatched = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.equals(m_lv1) && !dispatched) {
m_listAdapter1.setEnabled(true);
m_listAdapter2.setEnabled(false);
dispatched = true;
m_lv2.dispatchTouchEvent(event);
} else if (v.equals(m_lv2) && !dispatched) {
m_listAdapter1.setEnabled(false);
m_listAdapter2.setEnabled(true);
dispatched = true;
m_lv1.dispatchTouchEvent(event);
}
dispatched = false;
return false;
}
};
which works fine.
I also have OnItemClickListener for both of list views and it works fine as well
m_lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long arg) {
..
}
});
Now I add clickListener to sub-layout of the cells of list views.
if(viewHolder.layout_author != null) {
viewHolder.layout_author.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent profileIntent = new Intent(ImageListAdapter.this.activity, ProfileActivity.class);
profileIntent.putExtra("JsonUser", jsonAlbumImage.jsonUser);
ImageListAdapter.this.activity.startActivity(profileIntent);
}
});
}
Then, I find scrolling doesn't work sometimes.
I guess its because the new clickListener is consuming the touch events.
Any suggestion/guide is welcome.
You should implement interface OnItemClickListener and then use its Overrided method
onItemClick. set your listViews onItemClickListeners. Now in the Overrided Method "onItemClick" compare its parameter "parent" with your listViews.
e.g:
if (parent.equals(listView1)) {
/* your code here */
} else if(parent.equals(listView2){
/* your code here */
}
Related
I have an activity with a Spinner (with his own adapter) and another Adapter that manages the recycler view with its list . I'm trying to implement the following logic : when the list of the recycler is empty the spinner should be enabled , otherwise it should be disabled until the list is empty again :
sGames.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (pokemonCardsGridAdapter.getItemCount() == 0) {
v.performClick();
v.setEnabled(true);
} else {
v.setEnabled(false);
Toast.makeText(PokemonTeambuilderEditorActivity.this, "The list is full", Toast.LENGTH_SHORT).show();
}
return false;
}
});
However , this only works the first time , once the spinner gets disabled , it never receive any touch events again . How can I fix this?
Solved using registerAdapterDataObserver:
pokemonCardsGridAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
public void onChanged() {
sGames.setEnabled(false);
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
if (pokemonCardsGridAdapter.getItemCount() == 0) {
sGames.setEnabled(true);
}
}
});
Which is the most recommended way of handling click on RecyclerView items?
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
private RecyclerView.OnItemTouchListener itemTouchListener;
#Override
public boolean onInterceptTouchEvent(#NonNull RecyclerView recyclerView, #NonNull MotionEvent motionEvent) {
return false;
}
#Override
public void onTouchEvent(#NonNull RecyclerView recyclerView, #NonNull MotionEvent motionEvent) {}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean b) {}
});
Or setting a click listener on an item view inside the adapter?
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Do stuff
}
});
A Best and efficient way to get a click of recycler view item is by using interface as below:
1) First, define one interface as below
public interface OnListItemClick {
void onClick(View view, int position);
}
2) Now, set it from your fragment or activity
OnListItemClick onListItemClick = new OnListItemClick() {
#Override
public void onClick(View view, int position) {
// you will get click here
// do your code here
}
};
youradaptor.setClickListener(onListItemClick);
3) Now create one method in your adapter
public void setClickListener(OnListItemClick context) {
this.onListItemClick = context;
}
4) Now, from your itemview click use as below
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onListItemClick.onClick(view, getAdapterPosition()); // passing click to interface
}
});
Most common way it to use interfaces to handle onClick events inside a Recycler View.
Great read about this topic here
Go for your second opinion. But an interface should be implemented to handle the OnClick Event
I have an activity which creates a fragment with VerticalGridView.
In activity I have this:
#Override
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
if (fragment != null) {
if (fragment.handleKeyDown(keyCode)) {
return true;
}
// todo swallow some events
}
return super.onKeyDown(keyCode, event);
}
Since I need to do some special treatment for UP, DOWN, LEFT and RIGHT so I override this onKeyDown.
Then I have a custom viewHolder GridItemViewHolder extends RecyclerView.ViewHolder, in this viewHolder I have:
gridItemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LOG.d("onclick!!");
}
});
But this onclick method is never called when I press "Enter". Am I missing something here? Is onKeyDown override the onClick?
Thanks!!
Use OnItemClickListener for GridView
gridItemView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int i, long id) {
LOG.d("onclick!!"+i);
}
});
I using a List with Custom Adapter with ViewHolder and Item Views with Buttons.
I want to handle some stuff by clicking the Buttons in a Presenter.
How can i connect a Presenter with these Item Views?
You can use rx-android to observe AdapterView's click events the following way. It combines fine with MVP pattern used in Mortar.
At first dependencies:
compile 'io.reactivex:rxjava:1.0.4'
compile 'io.reactivex:rxandroid:0.24.0'
Then create observeClicks method in your view class.
public Observable<OnItemClickEvent> observeClicks() {
return WidgetObservable.itemClicks(adapterView);
}
Subscribe to events in your Presenter's onLoad:
private Subscription clicks;
#Override
protected void onLoad() {
super.onLoad();
clicks = getView().observeClicks().subscribe(
new Action1<OnItemClickEvent>() {
#Override
public void call(OnItemClickEvent event) {
// handle click events
}
}
);
}
protected void onDestroy() {
// unsubscribe from events
clicks.unsubscribe();
}
Also you can do mapping OnItemClickEvent to your data inside view already and observe it instead of raw events.
public Observable<YourDataClass> observeClicks() {
return WidgetObservable.itemClicks(adapterView).
map(new Func1<OnItemClickEvent, YourDataClass>() {
#Override
public YourDataClass call(OnItemClickEvent onItemClickEvent) {
YourDataClass item = adapter.getItem(onItemClickEvent.position());
return item;
}
});
}
Hope this comes in handy. At least I'm doing this that way, but certainly it is not the only solution.
ListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Handle your stuff here.
});
Something like this? Use the position to get the current item out of your List.
Buttons :
// In the adapter
Button butt = (Button) rowView.findViewById(R.id.yourbutton);
butt.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
//Button Action.
}
}
I am trying to add both OnClickListener and OnTouchListener to my image view. Following is how the image view is created
dialogImage = (ImageView)findViewById(R.id.dialogImage);
Following is how the listeners are set
dialogImage.setOnClickListener(dialogBoxClicked);
dialogImage.setOnTouchListener(imageViewSwiped);
Following is the listener method implementation
public OnClickListener dialogBoxClicked = new OnClickListener()
{
#Override
public void onClick(View v)
{
//To do has been removed because the code is too big
}
};
OnTouchListener imageViewSwiped = new OnSwipeTouchListener()
{
public void onSwipeRight()
{
currentlyActiveQuestion++;
currentWord = words.get(currentlyActiveQuestion);
setUI();
}
public void onSwipeLeft()
{
currentlyActiveQuestion--;
currentWord = words.get(currentlyActiveQuestion);
setUI();
}
};
Here the OnTouchListener is implemented by a class called OnSwipeTouchListener to monitor left and right swipes. This class can be found here - https://stackoverflow.com/a/12938787/1379286
But the problem now is, when I set the OnTouchListener to the image view, the OnClickListener is not responding / do not do what it should do. ImageView is only responding to OnTouchListener. If I remove OnTouchListener then the OnClickListener works. I tested this in a virtual device WVGA5.1 and Galaxy Nexus in eclipse and not in a real phone because I do not have one.
How can I solve this?
EDIT
Any code example will be greatly appreciated
You may call View.performClick() when action_up. This results in the click event being called when an actual click happens. Hope it helps.
your_txtView.setOnClickListener(new TextView.OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
your_txtView.setOnTouchListener(new TextView.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
} else if (MotionEvent.ACTION_UP == event.getAction()) {
v.performClick();
}
return true;
}
});
The OnTouchListener hooks the click-event. Handle the click event in it instead. Check out the answer on this question
From my experience, If you can't have both onTouchListener and onClickListener for the same view. If you want your onClickListener to work, set clickable="true" in the XML.