I have read about problems that onClickListener will consume onItemClickListener Events like here or here. My Problem is exactly the other way:
I have a CustomAdapter extends ArrayAdapter where I place model Objects to generate a row. In My Activity i registered an onItemClickListener like so
//items can focus false to try to get the onItemClick-event
mListView.setItemsCanFocus(false);
mListView.setOnItemClickListener(this);
mListView.setAdapter(this.favoritePointAdapter);
then in my Adapter.getView() Method I inflate my layout get my ImageView and register an OnClickListener on it like this
#Override
public View getView(int position, View convertView, ViewGroup parent){
//....inflate other Views.....
LinearLayout clickArea = (LinearLayout)convertView.findViewById(R.id.list_row_favorite_point_click_area);
clickArea.setOnClickListener(this);
//... other logic follows ...
}
at least i Try to fetch this Events in my Adapter like this
#Override
public void onClick(View v) {
Log.d("ListAdapter", "onClick triggered");
//never triggered
switch (v.getId()) {
case R.id.list_row_favorite_point_click_area:
Log.d("ListAdapter", "onClick id->list_row_favorite_point_click_area");
//never triggered
break;
default:
break;
}
}
If you find xml of RowView interesting, here it is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_row_relative_parent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="false">
<LinearLayout
android:id="#+id/list_row_icon"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="center_vertical"
android:layout_margin="3dip"
/>
<LinearLayout
android:layout_weight="50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical">
<TextView
android:id="#+id/list_row_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#333333"
android:text="defaultText"
android:textStyle="bold" />
<TextView
android:id="#+id/list_row_region"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#999999"
android:textStyle="italic"
android:text="Region" />
</LinearLayout>
<LinearLayout
android:id="#+id/list_row_favorite_point_click_area"
android:layout_width="50dip"
android:layout_height="50dip">
<ImageView
android:id="#+id/list_row_favorite_icon"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_gravity="center_vertical"
android:layout_weight="0.1">
</ImageView>
</LinearLayout>
</LinearLayout>
As I said, The ListView's onItemClick of My Activity gets triggered while I never reach onClick inside my Adapter. I think that onItemClick 'feels' responsible for the whole row and consumes TouchEvents. What can I do to work around it?
Note: I tried setItemsCanFocus(false) and focusable in my root to false, too, as mentioned in the other questions.
Rather than using an onClickListener, I'd suggest using the onTouchListener.
Check out this tutorial, which I have used before to get the "swipe screens" in an application:
http://www.warriorpoint.com/blog/2009/05/29/android-switching-screens-by-dragging-over-the-touch-screen/
Also, see the android dev docs on the onTouchListener:
http://developer.android.com/reference/android/view/View.OnTouchListener.html
Related
I have 3 Fragments inside my MainActivity and in one of my Fragments I have 3 ImageView and each of image view performs same action based on which ImageView was selected, now What I want to achieve is that instead of using OnClickListener for each of Views separately, call same method with switch-case or if-else inside. But the problem is those ImageViews inside fragment cannot call Functions implemented inside MainActivity. for instance. here's the code to understand what I want to say:
MAIN ACTIVITY
public void imageClicked(View v){
if(v.getID() == findViewById(R.id.id_of_imageView_1).getID()){
myTextView.setText("ImageView 1 is Clicked")
}
else if(v.getID() == findViewById(R.id.id_of_imageView_2).getID()){
myTextView.setText("ImageView 2 is Clicked")
}
else if(v.getID() == findViewById(R.id.id_of_imageView_3).getID()){
myTextView.setText("ImageView 3 is Clicked")
}
}
XML (fragment_images.xml) WHERE IMAGES EXIST
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/id_of_imageView_1"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="1"
android:src="#drawable/laptop" />
<ImageView
android:id="#+id/id_of_imageView_2"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="1"
android:src="#drawable/memory" />
<ImageView
android:id="#+id/id_of_imageView_3"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="1"
android:src="#drawable/screen" />
</LinearLayout>
</ScrollView>
XML (activity_main.xml) HERE I Link my Fragment and TextView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
//CHANGE THIS TEXT VIEW WHEN IMAGE IS CLICKED
<TextView
android:id="#+id/myTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="Select Product"
android:textSize="20sp"
android:textStyle="bold" />
<fragment
android:id="#+id/fragment_1"
android:name="com.salmanibrahim.calssifiedelectronics.ListFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_list" />
<fragment
android:id="#+id/fragment_2"
android:name="com.salmanibrahim.calssifiedelectronics.DetailFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_detail" />
//THIS IS THE FRAGMENT
<fragment
android:id="#+id/fragment_images"
android:name="com.salmanibrahim.calssifiedelectronics.AddProduct"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_images" />
</LinearLayout>
How do I call imageClicked() defined inside MainActivity using onClick on ImageView
In your fragment you can call imageClicked() in the MainActivity by using requireActivity() or getActivity() and do the necessary cast
In fragment:
public View onCreateView(...) {
View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
MainActivity mActivity = (MainActivity) requireActivity();
imageView1 = view.findViewById(...);
imageView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mActivity.imageClicked(imageView1);
}
});
...}
repeat the same for imageView2, 3
Also the condition in imageClicked() seems not right as you findViewById which will point to your MainActivity layout, not the fragment.
So you need to change this
if (v.getID() == findViewById(R.id.id_of_imageView_1).getID())
To
if (v.getID() == R.id.id_of_imageView_1)
And do the same for other images.
I understand what you trying to do but android:onClick parameter only links for the context declared in tools:context field on the parent tag of your layout file.
So it is not possible to reference your imageClicked() function found in your MainActivity from your fragment's ImageView because they are in different context. Check this for more info.
You are doing it in wrong way.
You can do this instead.
imageView_1.setOnClickListener(this);
then implement activity from View.onClickListener
then get view by id on the method that's been implemented.
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.id_of_imageView_1:
// do your things here
break;
}
}
I want to start an activity when i click on one of the item of my RecyclerView. Unfortunately when i click on an item nothing happens and I'm stuck here.
I think the code into the onClick method is right (But maybe I'm wrong). I tried to add a Log.d to see if the listener works but i can't see it in the logcat when i click on an item. I'm new on programming so it can be a stupid error. Thanks for help :)
public class UsersRecyclerAdapter extends RecyclerView.Adapter<UsersRecyclerAdapter.ViewHolder> {
private Context context;
private List<Users> usersList;
public UsersRecyclerAdapter(Context context, List<Users> usersList) {
this.context = context;
this.usersList = usersList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_row, parent, false);
return new ViewHolder(view, context);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Users users = usersList.get(position);
holder.firstName.setText(users.getFirstName());
holder.lastName.setText(users.getLastName());
holder.classe.setText(users.getClasse());
String avatarURL = users.getAvatar();
Picasso.get().load(avatarURL).into(holder.avatar);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("MyApp","I am here");
context = view.getContext();
Intent intent = new Intent(context, PDFPostListActivity.class);
// String userID = users.getUserID();
// intent.putExtra("userID", userID);
context.startActivity(intent);
}
});
}
EDIT. Here is the root view (users_row):
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageViewAVATAR"
android:layout_width="50dp"
android:layout_height="50dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp" />
<TextView
android:id="#+id/textViewfistName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
<TextView
android:id="#+id/textViewlastName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
<TextView
android:id="#+id/textViewclass"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
</LinearLayout>
</HorizontalScrollView>
</androidx.cardview.widget.CardView>
What's the root view of the view holder? Set it to be clickable since you set onClickListener on itemView of view holder.
Great thanks to #Mike M. who rapidly answer in the comment below the question. I paste the message:
When you call setOnClickListener() on itemView, it's setting that on the , since that's the outermost View there. The nested within it is preventing it from receiving click events. Assuming that's all that going to be in that layout, then the simplest fix would probably be to simply set the OnClickListener on the instead. You'll need to give it an android:id, find it with findViewById() just like you did the TextViews, and then call setOnClickListener() on that, instead of itemView.
I have a listview which occupies all the space of the layout IN THEORY, but actually it occupies only half of the layout because it has got only 5 elements and it doesn't cover all the screen. I'd like to know when I touch OUTSIDE of the listview. I tried to create a clicklistener method for the layout of the listfragment which contains the list, but it is never used because IN THEORY the listview occupies all the layout, so the click isn't found. It is the same for the layout of the activity more or less. In that case the click is found only on the edges, so I can't find a method to solve my problem.
Here is the fragment layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list" />
Here is the activity layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.utente.actionbar.MainActivity">
<Button
android:text="MULTI"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="26dp"
android:id="#+id/button" />
<Button
android:text="SINGOLO"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/button"
android:layout_alignLeft="#+id/button"
android:layout_alignStart="#+id/button"
android:layout_marginBottom="25dp"
android:id="#+id/button2" />
IN THEORY the listview occupies all the layout
Not a theory, that is exactly what happens; by using android:layout_height="match_parent" the View will always take the full screen height.
listView.setOnClickListener would work if you want to see if you clicked anywhere in the ListView, but you typically would instead want listView.setOnItemClickListener to see if you have clicked on any single item, and not the entire list.
Refer: difference between onClickListener and onItemClickListener
If you really want to shrink the ListView, then android:layout_height="wrap_content" is an option, but I'm not sure that works without content actually being loaded into that View since the content wrapping is applied at inflation-time, which since it has no adapter set, can't be done.
If you are needing to detect a listener literally "outside the ListView", then you need to set some type of click / touch listener on the rootView of that Fragment.
public View onCreateView(...) {
rootView = inflater.inflate(...);
listView = ...;
listView.setOnTouchListner(...
#Override
public boolean onTouch(View v, MotionEvent event) {
return false; // Says that click was not handled here.
}
});
rootView.setOnTouchListner(...
// TODO: Check if click landed outside the ListView
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() != android.R.id.listView) { // Not the list
if (event.getAction() == MotionEvent.ACTION_UP) {
// Up action more reliable than "down"
return true;
}
}
}
);
return rootView;
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content" <!-- Or specific height -->
android:id="#android:id/list" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/clickView" />
</LinearLayout>
In Fragmet
public View onCreateView(...) {
rootView = inflater.inflate(...);
View clickView = rootView.findViewById(...);
clickView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here
}
});
return rootView;
}
I guess this solves your problem.
So I have simple listview with a list item that contains a textview, and two imageviews.
I want both of the imageviews to act as buttons. Unfortunately, I can't even get one of them to work. The list view loads but then the app crashes when either image is touched. Here is the xml for the listitem:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_card">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textColor="#color/Black"
android:id="#+id/name"
android:textSize="20sp"
android:padding="16dp">
</TextView>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_gravity="right"
android:gravity="right">
<ImageView
android:layout_width="40dp"
android:layout_height="fill_parent"
android:id="#+id/email"
android:clickable="true"
android:src="#drawable/ic_action_email"
android:layout_margin="8dp"/>
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#color/LightGrey" />
<ImageView
android:layout_width="40dp"
android:layout_height="fill_parent"
android:id="#+id/internet"
android:clickable="true"
android:layout_margin="8dp"
android:src="#drawable/ic_action_web_site" />
</LinearLayout>
</LinearLayout>
Here is the layout with the listview:
<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="#+id/lvDepartments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:dividerHeight="8dp"
android:padding="8dp"
android:smoothScrollbar="true"
android:scrollbarStyle="insideOverlay"
android:listSelector="#color/Navy"/>
</LinearLayout>
Here is the related java code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.staff_layout);
staffmemberlist = (ListView)findViewById(R.id.lvDepartments);
ArrayAdapter<String> arrayAdapter =new ArrayAdapter<String> (getApplicationContext(),R.layout.emailbrowsingcard,R.id.name, d);
staffmemberlist.setAdapter(arrayAdapter);
mailbutton=(ImageView)findViewById(R.id.email);
mailbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),
"This line would appear on clicking this icon",
Toast.LENGTH_LONG).show();
}
});
}
this isnt going to work because the ImageView is in the item list so you should consider doing..
mailButton = (ImageView) row.findViewById(R.id.email);
where row is the item list. remember the ImageView isn't in staff_layout, it is in your item_layout.
to make it works you need to move this block:
mailbutton=(ImageView)findViewById(R.id.email);
mailbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),
"This line would appear on clicking this icon",
Toast.LENGTH_LONG).show();
}
});
to the getView() in your adapter class. and let the View get findViewById or have an instance of the item_layout view in order to reach the buttons.
you should use a custom adapter for that and in custom adapter use findViewById for finding imageviews and setting listener
this is a good tutorial: http://www.vogella.com/articles/AndroidListView/article.html
I can't seem to get an onClick event on an imageview from a class that extends Fragment. What am i doing wrong here? I'm relatively new to developing for android..
Currently, this code gives me a null pointer exception - when i add the onClickListener code
Here is my code:
ImageView mImageView = (ImageView) v.findViewById(R.id.option_icon);
mImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
these icons are placed in a listview which is placed on a Dialog:
Dialog's list view and button:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView android:id="#+id/preset_list_view"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
<Button
android:id="#+id/dialogButtonOK"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:text="#string/ok"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_below="#+id/image"/>
</LinearLayout>
items within the list view (imageview and textview):
<?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="match_parent" >
<ImageView
android:id="#+id/option_icon"
android:clickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/ic_launcher"
/>
<TextView
android:id="#+id/option_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/image"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="20dp" />
</RelativeLayout>
It must be that the ImageView you're trying to find it outside the scope of whatever v refers to.
If the image view is inside a list view then you should add the onClickListener from within the adapter
The imageView that you are trying to find is not accessible from v. If the imageView is in the main layout then use findViewById without using v else first inflate the view and then use view.findViewById.