how to handle long click in Android - java

I am new to Android dev. The way I have been handling clicks has been by setting the android:onClick attribute in the manifest file for buttons. What I am wondering is the best way to handle long clicks in general. I have read about implementing onLongClick(), but is there a way to use handlers (like above), rather than having to extend View? It would be very helpful, as I would rather not have to rebuild my entire project with an extended View class.
EDIT
I should clarify. I have a ListView and I want to set what will happen when I long click on an element in the list. Each element in the list is a TextView. As per one of the answers, I have added the below code, and now I get a force close:
public class TwitterActivity extends ListActivity {
List<String> tweets = new LinkedList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.layout, tweets));
TextView view = (TextView) findViewById(R.id.ListTemplate);
view.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast toast = new Toast(TwitterActivity.this);
toast.setText("LongClick");
toast.show();
return true;
}
});
//...
}
}

For a ListActivity if you want to respond to long clicks on the list elements do this:
public class TwitterActivity extends ListActivity {
List<String> tweets = new LinkedList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.layout, tweets));
ListView lv = getListView();
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id)
{
Toast.makeText(TwitterActivity.this, "LongClick", Toast.LENGTH_LONG).show();
}
});
}
}
For a regular activity you could do something like this:
public class MyActivity extends Activity implements View.onLongClickListener {
View myView = null;
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.my_activity);
myView = findViewById(r.id.my_view);
myView.setOnLongClickListener(this);
}
#Override
public void onLongClick(View v) {
//long clicked
}
}

get a handle to the button using findViewByID, then call setOnLongClickListener.
Button b = (Button)findViewByID (R.id.button1);
b.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//to do
}
});

Sure this is fairly simple:
ImageButton i = (ImageButton) findViewById(R.id.myButton);
i.setOnLongClickListener(new myLongListener());
private class myLongListener implements View.OnLongClickListener {
#Override
public void onClick(View v) {
//your code here
}
}
hope this helps!

You don't have to extend the View class in most cases. View has a method called setOnLongClickListener which you can use directly as all derived classes like Button or TextView, etc. will also have.

The only event handler that has an XML attribute is android:onClick. All other event handlers are registered at runtime from Java code. Technically, even android:onClick is registered at runtime from Java code, but you do not have to write the Java code in question.
So you need to do something like this:
View.OnLongClickListenerhandler = View.OnLongClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.myButton: // doStuff
break;
case R.id.myOtherButton: // doStuff
break;
}
}
}
findViewById(R.id.myButton).setOnLongClickListener(handler);
findViewById(R.id.myOtherButton).setOnLongClickListener(handler);

Related

RecyclerView how to setOnClickListener on every item?

What I want this code to do is: whenever the user clicks on the item (example: like or dislike),
I want something to happen to my firebase (eg. set the value of the like to 1).
I'm trying so hard to set a click listener for every item (like, dislike, happy emote, report).
Even if I set the click listener inside the static class, I can't call my Database Reference.
I also tried to do CommentsActivity.this.mReviewsDatabase..etc but it doesn't work because it doesn't want a static class. And if I remove the static from the class, the app crashes.
public class CommentsActivity extends AppCompatActivity {
private RecyclerView mCommentList;
public DatabaseReference mReviewsDatabase;
private FirebaseUser mCurrentUser;
private ImageView happyEmote, thumpUp, thumbDown ,reportReview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comments);
String title = getIntent().getStringExtra("EXTRA_SESSION_ID");
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
mReviewsDatabase = FirebaseDatabase.getInstance().getReference().child("Film_reviews").child(title);
mCommentList = (RecyclerView)findViewById(R.id.reviews_list);
mCommentList.setHasFixedSize(true);
mCommentList.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerAdapter<AllCommClass, CommentsActivity.ReviewsViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<AllCommClass, CommentsActivity.ReviewsViewHolder>(
AllCommClass.class,
R.layout.comment_single_layout,
CommentsActivity.ReviewsViewHolder.class,
mReviewsDatabase
) {
#Override
protected void populateViewHolder(CommentsActivity.ReviewsViewHolder reviewsViewHolder, AllCommClass allCommClass, int i) {
reviewsViewHolder.setUsername(allCommClass.getUsername());
reviewsViewHolder.setReview(allCommClass.getReview());
reviewsViewHolder.setVoto(allCommClass.getVoto());
reviewsViewHolder.setReport();
reviewsViewHolder.setLike();
reviewsViewHolder.setDislike();
reviewsViewHolder.setHappyEmote();
reviewsViewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { }
});
}
};
mCommentList.setAdapter(firebaseRecyclerAdapter);
}
public static class ReviewsViewHolder extends RecyclerView.ViewHolder {
View mView;
public ReviewsViewHolder(#NonNull View itemView) {
super(itemView);
mView = itemView;
}
public void setReport() {
ImageView reportReview = mView.findViewById(R.id.reportReview);
reportReview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v("Tag","You've reported the comment number "+getAdapterPosition());
}
});
}
public void setLike() {
ImageView thumpUp = mView.findViewById(R.id.thumbUp);
thumpUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v("Tag","You've liked the comment number "+getAdapterPosition());
}
});
}
public void setDislike() {
ImageView thumpDown = mView.findViewById(R.id.thumbDown);
thumpDown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v("Tag","You've disliked the comment number "+getAdapterPosition());
}
});
}
public void setHappyEmote() {
ImageView happyEmote = mView.findViewById(R.id.happyEmote);
happyEmote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v("Tag","You've added a reaction to the comment number "+getAdapterPosition());
}
});
}
public void setUsername(String username){
TextView titleView = mView.findViewById(R.id.user_single_username_comment_section);
titleView.setText(username);
}
public void setReview(String review){
TextView titleView = mView.findViewById(R.id.user_single_review);
titleView.setText(review);
}
public void setVoto(int voto){
TextView titleView = mView.findViewById(R.id.user_single_rating);
titleView.setText(String.valueOf(voto));
}
}}
"
There are basically 2 ways as a beginner to set click listener to a recycler view item.
The first was is the easy but nonoptimal way to do it. Inside your onBindViewHolder of your adapter class set an onClickListener to your holder.itemview
The second way is to use an onClickInterface and then call it from the calling/main activity. Please let me know if you need any further guidance
When we are fetching data from firebase
The process is to match the Id of the item on firebase you are fetching through your model class to populate your recycleView.
If you want your application to remember the number of like or dislike on a certain button you need to set count on the id of the item on which the user will perform the click.
You can show that count or keep track of the button click in that manner.
If you need the code for it let me know

Can't get selected spinner item outside #Override method and into another class

I have MainActivity and SpinnerActivity, I want to get selected spinner item value from SpinnerActivity into the MainActivity. I tried to declare String as Static, I also tried with getter but without any success.
in Spinner Activity I also have if statement, how can I get value outside "if statement" and "#Override method" into another class?
MainActivity.class
public class MainActivity extends AppCompatActivity {
SpinnerActivity spinnerActivity = new SpinnerActivity();
Spinner spinnerProvince;
String selectedSpinnerProvince = spinnerActivity.inSpinnerSelectedProvince;
// String selectedSpinnerProvince = SpinnerActivity.inSpinnerSelectedProvince;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinnerProvince = findViewById(R.id.spinnerProvince);
populateSpinnerProvinces();
spinnerProvince.setOnItemSelectedListener(spinnerActivity);
}
public void populateSpinnerProvinces() {
ArrayAdapter<String> provincesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.province));
provincesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProvince.setAdapter(provincesAdapter);
}
}
SpinnerActivity.class
public class SpinnerActivity implements android.widget.AdapterView.OnItemSelectedListener {
public String inSpinnerSelectedProvince;
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.spinnerProvince) {
inSpinnerSelectedProvince = parent.getItemAtPosition(position).toString();
Toast.makeText(parent.getContext(), parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();
} else {// code here}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
I were about to advice you to use Intent to share data between both activities when i noticed that your "SpinnerActivity" is not really an Activity since it not extends Android Activity class (AppCompactActivity or other classes like this).
Your SpinnerActivity is a Listener. You can use it to implement the action to trigger when an action is performed on your Spinner view. For that you need to do it inside the "#Override" method of onItemSelected.
If you don't like to use the previous methode because of the Override methode you should implement directly the action to trigger at on click events on your spinner view in your MainActivity by doing this:
public class MainActivity extends AppCompatActivity {
SpinnerActivity spinnerActivity = new SpinnerActivity();
Spinner spinnerProvince;
String selectedSpinnerProvince = spinnerActivity.inSpinnerSelectedProvince;
// String selectedSpinnerProvince =
SpinnerActivity.inSpinnerSelectedProvince;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinnerProvince = findViewById(R.id.spinnerProvince);
populateSpinnerProvinces();
//spinnerProvince.setOnItemSelectedListener(spinnerActivity);
spinnerProvince.setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.spinnerProvince) {
inSpinnerSelectedProvince = parent.getItemAtPosition(position).toString();
Toast.makeText(parent.getContext(), parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();
} else {// code here}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
public void populateSpinnerProvinces() {
ArrayAdapter<String> provincesAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item,
getResources().getStringArray(R.array.province));
provincesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProvince.setAdapter(provincesAdapter);
}
}

How to show/hide BottomSheetDialogFragment without recreating it?

I am using BottomSheetDialogFragment in my android app. I am using Java. I show the bottomsheet by:
ActionBottomDialogFragment dialogFragment = ActionBottomDialogFragment.newInstance();
showButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialogFragment.show(getActivity().getSupportFragmentManager(), ActionBottomDialogFragment.TAG);
}
});
What I see is it calls onCreateDialog method and then calls onViewCreated methods. For the first time this is okay.
Now I hide the bottom sheet using:
ImageButton close = view.findViewById(R.id.closeButton);
close.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
Then when I press the show button again, it calls onCreateDialog method again. I have a dynamic list of choice chips which I want the state to be just as I left it. If I left it on checking 'Choice A', it should show up selected the next time I open the bottom sheet. I need the state to be maintained.
What is happening is it rebuilds the choice chips from start, so the state is lost.
How can I just show / hide the bottom sheet without recreating?
UI will be always created again when you call show(). It's better to use a sharedViewModel in bottomSheetFragment and the parent activity/fragment. You should save the fields being selected in the viewmodel and use it the bottomSheet. This way the state will be maintained.
You can use show() & hide() of the dialog itself; this will keep the fragment alive.
So, in your case:
To show it:
ActionBottomDialogFragment dialogFragment;
showButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (dialogFragment == null) {
dialogFragment = ActionBottomDialogFragment.newInstance();
dialogFragment.show(getActivity().getSupportFragmentManager(), ActionBottomDialogFragment.TAG);
} else {
dialogFragment.getDialog().show();
}
}
});
And to hide it:
ImageButton close = view.findViewById(R.id.closeButton);
close.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialogFragment.getDialog().hide();
}
});
But this requires to handle the side effects when dismissing the fragments using the back button and when touching outside.
Here's a custom DialogFragment that handles that:
public class BottomSheet extends BottomSheetDialogFragment {
public BottomSheet() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_layout, container, false);
return view;
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
return new BottomSheetDialog(requireContext(), getTheme()) {
#Override
public void onBackPressed() {
getDialog().hide();
}
};
]
}
#SuppressLint("ClickableViewAccessibility")
#Override
public void onStart() {
super.onStart();
setCancelable(false);
getDialog().setCanceledOnTouchOutside(false);
final View outsideView =
requireDialog().findViewById(com.google.android.material.R.id.touch_outside);
outsideView.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP)
getDialog().hide();
return false;
});
}
}

Button in MainActivity, Reset spinner in a DialogFragment

I have two buttons in MainActivity, the first one opens a custom DialogFragment with some spinners and in the other button it resets the spinners of this DialogFragment.
When I click the reset button it calls this method that is in the DialogFragment:
public class FilterDialogFragment extends DialogFragment {
private View view;
// ...
#Nullable
#Override
public View onCreateView(#NotNull LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.dialog_filters, container, false);
// start the spinners and adapters here
return view;
}
public void resetFilters() {
if (view != null) {
categorySpinner.setSelection(0);
productSpinner.setSelection(0);
priceSpinner.setSelection(0);
}
}
// some more codes here
}
My MainActivity:
public class MainActivity extends AppCompatActivity {
private FilterDialogFragment filterDialog;
private Button button_clear;
private Button button_filter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_clear = findViewById(R.id.button_clear);
button_filter = findViewById(R.id.button_filter);
filterDialog = new FilterDialogFragment();
button_filter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Show the dialog containing filter options
filterDialog.show(getSupportFragmentManager(), FilterDialogFragment.TAG);
}
});
button_clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//reset all filters
filterDialog.resetFilters();
}
});
//some more codes here
}
//some more methods here
}
But by clicking the button that opens the DialogFragment, the values of the Spinners remain the same instead of returning the data of position 0 of each spinner.
Would anyone know how to solve this? I've tried everything and I can not.
The simplest way I ended up finding, was to delete the resetFilters method, and instead I did so:
button_clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//reset all filters
filterDialog = new FilterDialogFragment(); }
});

Issue with onClickListener for Button in Fragment

I have a button in a fragment class that I'd like to have trigger a method in the parent activity. I've implemented an interface for this.
My issue is that the View.onClickListener is giving me the following error:
Class 'Anonymous class derived from onClickListener' must either be declared abstract or implement abstract method 'onClick(View)' in 'onClickListener'
Which is odd, because I'm implementing onClick(View).
Here is the code in my Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(com.zlaporta.chessgame.R.layout.gamedescfragment, container, false);
final Button make_move = (Button) v.findViewById(R.id.make_move);
make_move.setOnClickListener(new ***View.OnClickListener()*** {
public void OnClick(View v) {
makeMoveCallback.makeMoveMethod();
}
});
The stars indicate the portion of the code that Android Studio doesn't like.
Do it using Anonymous inner class in an object:
//declaring OnClickListener as an object
private OnClickListener btnClick = new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
};
//passing listener object to button
make_move.setOnClickListener(btnClick);
Hope this will help :)
Just a typo: Replace the method name
OnClick
with
onClick
Could you try passing the OnClickListener from a method
e.g.,
private View.OnClickListener getButtonOnClickListener() {
return new View.OnClickListener() {
#Override
public void onClick(View v) {
// this is the code
}
};
}
and then using make_move.setOnClickListener(getButtonOnClickListener());
This is best way to using click event for button. using onClick listener implementing. use below code.
public class MyFragment extends Fragment implements OnClickListener {
Button mButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_layout, null);
mButton = (Button) view.findViewById(R.id.button1);
mButton.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
if (v == mButton) {
// Do something on click button
}
}
}
If using every click event separately it take more space. its better to use this code.
Add #Override above onClick method
Or you can use below method of button click Listener in OnActivityCreated() methos of Fragment.
make_move.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
makeMoveCallback.makeMoveMethod();
}
});

Categories

Resources