I'm using this library: https://github.com/prolificinteractive/material-calendarview in my project. Here are segments of my code. I used the EventDecorator class that was provided in the documentation for the Dot Span and renamed it. The calendarView is a MaterialCalendarView in the EventFragment. I wanted to add a Dot Span whenever I click on a specific date in the calendarView, but it doesn't seem to be working/showing up. markedDates is an array list containing all the CalendarDay that were clicked on, so every time I click on a specific date in the calendarView, I add the CalendarDay to the array list. Does anyone know how to fix this/make it work?
public class CurrentDayDecorator implements DayViewDecorator {
private final int color;
private final HashSet<CalendarDay> dates;
public CurrentDayDecorator(int color, Collection<CalendarDay> dates) {
this.color = color;
this.dates = new HashSet<>(dates);
}
#Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day);
}
#Override
public void decorate(DayViewFacade view) {
view.addSpan(new DotSpan(5, color));
}
}
In EventFragment class
calendarView.setOnDateChangedListener(new OnDateSelectedListener() {
#Override
public void onDateSelected(#NonNull MaterialCalendarView widget, #NonNull CalendarDay date, boolean selected) {
markedDates.add(date);
currentDayDecorator = new CurrentDayDecorator(Color.WHITE, markedDates);
widget.addDecorator(currentDayDecorator);
widget.invalidateDecorators();
}
});
I know it's already too late but my solution can be beneficial for a lot more as I myself couldn't find a good implementation of adding dots. I will be showing a simple implementation of putting a red color dot on all those dates where user gonna click and I believe you can customise things accordingly. So, here we go.
First thing first, make a new java class "EventDecorator" and copy all the following code inside that-
public class EventDecorator extends AppCompatActivity implements DayViewDecorator {
private final int color = Color.parseColor("#FF0000");
private final CalendarDay dates;
public EventDecorator(CalendarDay dates) {
this.dates = dates;
}
#Override
public boolean shouldDecorate(CalendarDay day) {
return dates==day;
}
#Override
public void decorate(DayViewFacade view) {
view.addSpan(new DotSpan(5, color));
}
}
Now come to the fragment where we will be setting up the onDateChangegListener, So, copy all this code there inside the createView-
CalendarView calendarView = view.findViewById(R.id.calendarView); //remove view. if it's an activity
calendarView.setOnDateChangedListener(new OnDateSelectedListener() {
#Override
public void onDateSelected(#NonNull MaterialCalendarView widget, #NonNull CalendarDay date, boolean selected) {
EventDecorator eventDecorator= new EventDecorator(date);
widget.addDecorator(eventDecorator);
widget.invalidateDecorators();
}
});
So this is how things are working and if you want to use these dots only on those dates with some events then you can make an array of these dates, store them and then pass them to the EventDecorator class.
Hope this helps someone. Be free to ask anything.
Related
I can save bold, italic, and much more format, But Colored Text is not saved.
I am using RichText library. Can you help me?
thank you.
Here is my color picker code...
findViewById(R.id.action_txt_color).setOnClickListener(v -> {
openColorPicker();
});
private void openColorPicker() {
final ColorPicker colorPicker = new ColorPicker(InputActivity.this);
ArrayList<String>color = new ArrayList<>();
color.add("#FF0000");
color.add("#00FFFF");
color.add("#0000FF");
color.add("#00008B");
color.add("#FFFF00");
color.add("#00FF00");
color.add("#C0C0C0");
colorPicker.setOnFastChooseColorListener(new ColorPicker.OnFastChooseColorListener() {
#Override
public void setOnFastChooseColorListener(int position, int color) {
editor.setTextColor(color);
}
#Override
public void onCancel() {
editor.removeFormat();
}
}).setColumns(5).show();
}
i using a specific date library(https://github.com/mohamad-amin/PersianMaterialDateTimePicker)
now i want using it in a button in Recycler View.
now my problem is I have to define two options in library codes :
1 - I should refer to the activity.
2 - i need to use getSupport FragmentManager().
but this page has been extends with Recycler View.Adapter and I do not know how to call these two options on this page.
RecyclerViewAdapter page :
PersianCalendar persianCalendar = new PersianCalendar();
DatePickerDialog datePickerDialog = DatePickerDialog.newInstance( StudentList.this ,
persianCalendar.getPersianYear() ,
persianCalendar.getPersianMonth() ,
persianCalendar.getPersianDay());
datePickerDialog.show( getSupportFragmentManager() , "datePickerDialog" );
In these pictures you can easily understand me :
enter image description here
enter image description here
enter image description here
You activity must implements TimePickerDialog.OnTimeSetListener and implement the abstact methode onTimeSet:
public class StudentList extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {
#Override
public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) {
}
}
and inside onClick
DatePickerDialog datePickerDialog = DatePickerDialog.newInstance((((StudentList)view.getContext()), persianCalendar.getPersianYear(),
persianCalendar.getPersianMonth(),
persianCalendar.getPersianDay());
OR :
DatePickerDialog datePickerDialog =DatePickerDialog.newInstance(new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
}
}, persianCalendar.getPersianYear(),
persianCalendar.getPersianMonth(),
persianCalendar.getPersianDay());
You could try passing the Activity's context when creating an instance of the adapter:
//Code in your Activity
MyAdapter myAdapter = new MyAdapter(this, ...);
Your adapter:
private Context context;
public MyAdapter(Context context, ...){
this.context = context;
//Rest of the constructor...
}
By doing that, you could just add do this:
datePickerDialog.show(context.getSupportFragmentManager(), "datePickerDialog");
You just need an activity context passed in your constructor. Be sure to call new Adapter(this,...) from activities and new Adapter(getActivity(),...) from fragments.
private Context context;
#Override
public void onClick(View v) {
FragmentManager manager = ((Activity) context).getFragmentManager();
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
}
try this
I have an android application where a MapsActivity is included to display a number of markers using GoogleMaps.
The markers are created through Timestamp objects
Timestamp object attributes
(double lat,lon;
int stepSum;
long timeMilli;
String state=null;)
stored in Firebase Database.
So I retrieve each Timestamp from the database and try to create a marker with those attibutes above. My problem is that when I click a marker the custom info window is being displayed but its the same for all markers. It should show different attributes for different markers.
Why this is happening
In the drawMarkers() method I instantiate a separate infowindow when I am creating a new marker and set that info window to the
GoogleMap object with mMap.setInfoWindowAdapter(infoWindow);.
As I result mMap.setInfoWindowAdapter(infoWindow);is called as many times as markers are created and finally only the last infowindow survives. That is the problem but I can't figure out a solution.
How to implement an infowindow that when I click a marker it presents some kind of data and when I am clicking another marker it presents different kind of data (same layout, different attributes).
A valid example also would do.
CustomInfoWindow class
private class CustomInfoWindow implements GoogleMap.InfoWindowAdapter{
private String title=null,hour=null,state=null;
private int steps=0;
public CustomInfoWindow(){}
public CustomInfoWindow(String title, String hour, String state, int steps) {
this.title = title;
this.hour = hour;
this.state = state;
this.steps = steps;
}
#Override
public View getInfoWindow(Marker marker) {
return null;
}
public void setState(String state) {
this.state = state;
}
#Override
public View getInfoContents(Marker marker) {
LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
View root = inflater.inflate(R.layout.marker_infowindow,null);
TextView titleTextView = (TextView) root.findViewById(R.id.infowindow_title);
TextView hourTextView = (TextView) root.findViewById(R.id.infowindow_hour);
TextView stepsTextView = (TextView) root.findViewById(R.id.infowindow_steps);
TextView stateTextView = (TextView) root.findViewById(R.id.infowindow_state);
titleTextView.setText(title);
if (state!=null){
stateTextView.setText(getApplicationContext().getString(R.string.state)+" "+state);
stateTextView.setVisibility(View.VISIBLE);
}
hourTextView.setText(getApplicationContext().getString(R.string.time)+" "+hour);
stepsTextView.setText(getApplicationContext().getString(R.string.steps_so__far)+" "+steps);
return root;
}
public void setTitle(String title) {
this.title = title;
}
public void setHour(String hour) {
this.hour = hour;
}
public void setSteps(int steps) {
this.steps = steps;
}
}
How markers are drawn
private void drawMarkers(Calendar c){
String userId = this.user.getAccount().getId();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
final DatabaseReference timestampRef = FirebaseDatabase.getInstance().getReference()
.child(FirebaseConstant.TIMESTAMPS.toString());
timestampRef.child(userId).child(""+year).child(""+month).child(""+dayOfMonth)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long childCounter=0;
for (DataSnapshot timestampSnapshot:dataSnapshot.getChildren()){
CustomInfoWindow infoWindow=new CustomInfoWindow();
Timestamp temp = timestampSnapshot.getValue(Timestamp.class);
if (temp!=null){
infoWindow.setTitle(getString(R.string.todays_timestamp));
infoWindow.setHour(getFormatedHourFromTimeMilli(temp.getTimeMilli()));
infoWindow.setSteps(temp.getStepSum());
if (temp.getState()!=null){
infoWindow.setState(temp.getState());
}
mMap.setInfoWindowAdapter(infoWindow);
drawTimestamp(temp);
infoWindow=null;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
I have read google's tutorial about info windows but couldn't solve my problem.
Hope this example will help you just use it as simple xml layout.
Remember button will not work just textview will complete your requirement on the spot if you want get buttons in workable condition follow chose007 example.
My solution
Create a class that extends GoogleMap.InfoWindowAdapter. That will be your custom infowindow for the whole map.
Inside onMapReady() set an implementation of your customInfoWindow object to the GoogleMap object. That will be the one and only infowindow that it will be displayed when a user is clicking a marker from the map.
Finally, inside onMapReady() method set an OnMarkerClickListener to the GoogleMap object as well. Your implementation of the GoogleMap.OnMarkerClickListener.onMarkerClick(Marker marker) will only change the content (change the attributes of the infowindow object, call it however you want) of the infowindow, depending on which marker is clicked.
I want to change the color of one word when I touch it.
For example: Hello, my name is Robert.
(by default, all black)
Now if the user touches the word "Robert", I want the color of "Robert" to change to RED.
How do I do that? (I'm new to Android)
textview.setTextColor() changes the whole thing, I only want one word.
I believe the SpannableString and ClickableSpan are the things you are looking for.
For more information, check this.
And Html.fromHtml is also work for this.
L. Swifter is on the right track.
Here's a very simple version you can build off of.
SpannableString spannableString = new SpannableString(yourstring);
ClickableSpan clickableSpan = new ClickableSpan() {
boolean clicked = false;
#Override
public void onClick(View view) {
clicked = true;
view.invalidate();
}
#Override
public void updateDrawState(TextPaint ds) {
if (this.clicked) ds.setColor(Color.RED);
}
};
spannableString.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(spannableString);
textview.setMovementMethod(LinkMovementMethod.getInstance());
start and end are the index positions of "Robert"
Make sure your setText is using the spannableString, not the original string.
Have fun!
You can add an HTML <font> tag to the TextView's text.
Use onTouch to calculate which word you just touched, look at this.
And :
TextView.setText(Html.fromHtml("assumble your html style string to change specified word color"));
Summarize the answer of L. Swifter and TML, also used the answer from
select a word on a tap in TextView/EditText
The following code should be work if you click any word in the TextView.
The color would be changed to red if you clicked it. Other words color will be reset to black.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView lTextView = (TextView) findViewById(R.id.textView);
breakEveryWord("Clickable words in text view ", lTextView);
}
...
private void breakEveryWord(String passage, final TextView pTextView) {
String definition = passage.trim();
pTextView.setMovementMethod(LinkMovementMethod.getInstance());
pTextView.setText(definition, TextView.BufferType.SPANNABLE);
final Spannable spans = (Spannable) pTextView.getText();
BreakIterator iterator = BreakIterator.getWordInstance(Locale.US);
iterator.setText(definition);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
.next()) {
String possibleWord = definition.substring(start, end);
if (Character.isLetterOrDigit(possibleWord.charAt(0))) {
ClickableSpan clickSpan = new CustomClickableSpan(possibleWord, new CallBack() {
#Override
public void clearAll() {
CustomClickableSpan[] toRemoveSpans = spans.getSpans(0, pTextView.getText().length(), CustomClickableSpan.class);
for (CustomClickableSpan toRemoveSpan : toRemoveSpans) {
toRemoveSpan.reset(pTextView);
}
}
});
spans.setSpan(clickSpan, start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
public static class CustomClickableSpan extends ClickableSpan {
final String mWord;
boolean clicked = false;
final CallBack mCallBack;
public CustomClickableSpan(String pWord, CallBack pCallBack) {
mWord = pWord;
mCallBack = pCallBack;
}
public void reset(View widget) {
clicked = false;
widget.invalidate();
}
#Override
public void onClick(View widget) {
Log.d("tapped on:", mWord);
mCallBack.clearAll();
clicked = true;
widget.invalidate();
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.BLACK);
if (this.clicked) ds.setColor(Color.RED);
}
}
public interface CallBack {
void clearAll();
}
}
I have an app where the user can use a color picker or pre-defined buttons to change the background of their quotes. I want to make it possible that the user can change the color of the predefined buttons with a longclick and then a color picker appears and the user can now choose to save any color to the button.
For some reason the color pickers listener methods dosn't work in my RecyclerView adapter. The color picker listener should give me the current seleceted color. I have tested it with a Log.d("TAG", ""+color);
and I dont get any values
The RecyclerView adapater's Viewholder for background colors:
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener, ColorPickerDialogFrag2.ColorPickerDialogListener {
public ImageButton colorButton;
public ViewHolder(View itemView) {
super(itemView);
this.colorButton = (ImageButton) itemView.findViewById(R.id.colorbutton);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
#Override
public void onClick(View v) {
int position = getLayoutPosition();
MainActivity.relativeLayout.setBackgroundColor(Color.parseColor((mColorButtons.get(position).getColor())));
PreferenceManager.getDefaultSharedPreferences(App.getAppContext()).edit().putInt(App.BACKGROUND, Color.parseColor(mColorButtons.get(position).getColor())).apply();
//ColorPicker for customizing colors for buttons
#Override
public boolean onLongClick(View v) {
ColorPickerDialogFrag2 cp = ColorPickerDialogFrag2.newInstance(6, Color.YELLOW);
cp.setStyle(android.support.v4.app.DialogFragment.STYLE_NORMAL, R.style.AppTheme);
cp.show(fragmentManager,"d");
return false;
}
#Override
public void onPreviewColorChanged(int dialogId, int color) {
//color is the current color from the colorpicker
Log.d("TAG", ""+color);
MainActivity.mEditText.setBackgroundColor(color);
}
#Override
public void onColorSelected(int dialogId, int color) {
Log.d("TAG", ""+color);
MainActivity.mEditText.setBackgroundColor(color);
}
}
Here is an video of how it currently works in my app:
https://www.youtube.com/watch?v=lpYjKMLd9aU
The Color Picker libray I use is this: https://github.com/danielnilsson9/color-picker-view
The problem is that you implement ColorPickerDialogListener for your ViewHolder, but looking through the code of library here, you could see that it tries to cast activity as a ColorPickerDialogListener, otherwise it throws the exception. So try to implement this listener on your MainActivity and see the result.
UPDATE:
So in that case you need to change logic of your ColorPickerDialogFrag2 to something like this:
...
private ColorPickerDialogListener mListener;
public static ColorPickerDialogFrag2 newInstance(ColorPickerDialogListener listener,
int dialogId, int initialColor) {
ColorPickerDialogFrag2 frag = new ColorPickerDialogFrag2();
frag.setListener(listener);
Bundle args = new Bundle();
args.putInt("id", dialogId);
args.putInt("init_color", initialColor);
frag.setArguments(args);
return frag;
}
public void setListener(ColorPickerDialogListener mListener) {
this.mListener = mListener;
}
...
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (mListener == null) {
// Check for listener in parent activity
try {
mListener = (ColorPickerDialogListener) activity;
} catch (ClassCastException e) {
e.printStackTrace();
throw new ClassCastException("Parent activity must implement "
+ "ColorPickerDialogListener to receive result.");
}
}
}
...
And then just pass ColorPickerDialogListener as a parameter to newInstance method:
#Override
public boolean onLongClick(View v) {
ColorPickerDialogFrag2 cp = ColorPickerDialogFrag2.newInstance(this, 6, Color.YELLOW);
cp.setStyle(android.support.v4.app.DialogFragment.STYLE_NORMAL, R.style.AppTheme);
cp.show(fragmentManager,"d");
return false;
}