Android view onClick event not passed to self - java

I'm extending the EditText class in android to incorporate additional functionality one of which is to display a dialog when clicked. I want the behaviour to be portable and hence self contained.
However setting onClickListener to itself (this) as parameter has no effect and the function onClick(View) is never called.
public class TimePickerEditText extends EditText implements View.OnClickListener, TimePickerDialog.OnTimeSetListener {
private Calendar today;
private TimePickerDialog timePickerDialog;
public TimePickerEditText(Context context) {
super(context);
postInstantiateSetup();
}
public TimePickerEditText(Context context, AttributeSet attrs) {
super(context, attrs);
postInstantiateSetup();
}
public TimePickerEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
postInstantiateSetup();
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
postInstantiateSetup();
}
public void postInstantiateSetup()
{
setOnClickListener(this);
today = Calendar.getInstance();
onTimeSet(null,today.get(Calendar.HOUR_OF_DAY),today.get(Calendar.MINUTE));
}
#Override
public void onClick(View view) {
if(timePickerDialog == null) {
timePickerDialog = new TimePickerDialog(getContext(), this, 20, 0, true);
}
timePickerDialog.show();
}
#Override
public void onTimeSet(TimePicker timePicker, int hours, int minutes) {
String hoursString = ""+hours;
if(hours<10)
hoursString="0"+hoursString;
String minutesString = ""+minutes;
if(minutes<10)
minutesString="0"+minutesString;
this.setText(hoursString+":"+minutesString);
}
}

Related

(MVC) Implement TextWatcher on Compound view

I am new to MVC and I am trying to create a Color picker Android app for school. The purpose is to create multiple compound views to display the same data (the red, green and blue values). My question is how should I use TextWatcher to determine when the EditText field has been changed and then update all views based on the value of the field. Here is my code so far:
ColorModel.java
public class ColorModel extends Observable {
private int red, green, blue;
public void updatedColorModel() {
this.setChanged();
this.notifyObservers();
}
/**
* Change the value of the RED color
* #param value
*/
public void setRed(int value) {
this.red = value;
updatedColorModel();
}
/**
* Change the value of the GREEN color
* #param value
*/
public void setGreen(int value) {
this.green = value;
updatedColorModel();
}
/**
* Change the value of the BLUE color
* #param value
*/
public void setBlue(int value) {
this.blue = value;
updatedColorModel();
}
public int getRed() {
return this.red;
}
public int getGreen() {
return this.green;
}
public int getBlue() {
return this.blue;
}
}
ETColorsCOMP.java (a Compound of 3 EditTexts)
public class ETColorsCOMP extends ConstraintLayout implements Observer {
private EditText etRed, etGreen, etBlue;
private ColorModel model;
public ETColorsCOMP(Context context) {
super(context);
init();
}
public ETColorsCOMP(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ETColorsCOMP(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void init() {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.edittext_compound, this);
etRed = findViewById(R.id.editTextRed);
etGreen= findViewById(R.id.editTextGreen);
etBlue = findViewById(R.id.editTextBlue);
}
public void setColorModel(ColorModel model) {
this.model = model;
this.model.addObserver(this);
}
#Override
public void update(Observable observable, Object o) {
etRed.setText(model.getRed());
etGreen.setText(model.getGreen());
etBlue.setText(model.getBlue());
}
}
VColorsCOMP.java (a Compound of 3 View Components)
public class VColorCOMP extends ConstraintLayout implements Observer {
private ColorModel model;
private View vRed, vGreen, vBlue;
public VColorCOMP(Context context) {
super(context);
init();
}
public VColorCOMP(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public VColorCOMP(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void init() {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.colorview_compound, this);
vRed = findViewById(R.id.ViewRed);
vGreen = findViewById(R.id.ViewGreen);
vBlue = findViewById(R.id.ViewBlue);
}
public void setColorModel(ColorModel model) {
this.model = model;
this.model.addObserver(this);
}
#Override
public void update(Observable observable, Object o) {
vRed.setBackgroundColor(Color.rgb(model.getRed(), 0, 0));
vGreen.setBackgroundColor(Color.rgb(0, model.getGreen(), 0));
vBlue.setBackgroundColor(Color.rgb(0, 0, model.getBlue()));
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ETColorsCOMP etColors;
private VColorCOMP vColor;
private ColorModel colorModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etColors = findViewById(R.id.editTextView);
vColor = findViewById(R.id.colorView);
colorModel = new ColorModel();
etColors.setColorModel(colorModel);
vColor.setColorModel(colorModel);
}
}
I will be very grateful if somebody helps me to make this work.
You can write your code on afterTextChanged method of TextWatcher for this.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
// Update UI
}
});

SeekBar.java has error

I have this SeekBar.java :
package android.widget;
import android.content.Context;
import android.util.AttributeSet;
public class SeekBar extends AbsSeekBar {
public interface OnSeekBarChangeListener {
void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser);
void onStartTrackingTouch(SeekBar seekBar);
void onStopTrackingTouch(SeekBar seekBar);
private OnSeekBarChangeListener mOnSeekBarChangeListener;
public SeekBar(Context context) {
this(context, null);
}
public SeekBar(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.seekBarStyle);
}
public SeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public SeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
void onProgressRefresh(float scale, boolean fromUser, int progress) {
super.onProgressRefresh(scale, fromUser, progress);
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, progress, fromUser);
}
}
public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
mOnSeekBarChangeListener = l;
}
#Override
void onStartTrackingTouch() {
super.onStartTrackingTouch();
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStartTrackingTouch(this);
}
}
#Override
void onStopTrackingTouch() {
super.onStopTrackingTouch();
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStopTrackingTouch(this);
}
}
#Override
public CharSequence getAccessibilityClassName() {
return SeekBar.class.getName();
}
}
The Override lines in onProgressRefresh, onStartTrackingTouch, onStopTrackingTouch give this error :
Method does not override from its super class.
And this problem causes another error in my code, how can I fix this? Thanks.
SeekBar extends AbsSeekBar
AbsSeekBar doesn't have a method named onProgressRefresh yet you are using the override annotation.
The onProgressRefresh is in OnSeekBarChangeListener interface.
I am guessing you forgot to write implents.
SeekBar extends AbsSeekBar implements OnSeekBarChangeListener
That error means that its super class does not have those methods(onProgressRefresh, onStartTrackingTouch, onStopTrackingTouch). If you want to override those methods, you shall check the super class. Or you just remove #Override

Using onClick() defined in separate class in ViewHolder

I have a RecyclerView holding CardViews with a favorite button within each card. I would like the favorite button to only be clicked for each specific card. I am currently using a ViewHolder to maintain each of the components in each card and the favorite button is one of those components.
How can I use an onClick() defined in a separate class within the ViewHolder?
Using this code currently only actives the onTouchEvent() for the favoriteButton
viewHolder.favoriteButton.setOnClickListener(new LikeButtonView(mContext));
AppAdapter.java
public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> {
PackageManager packageManager;
private List<App> apps;
private int rowLayout;
private Context mContext;
public AppAdapter(List<App> apps, int rowLayout, Context context) {
this.apps = apps;
this.rowLayout = rowLayout;
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
packageManager = this.mContext.getPackageManager();
View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
App appObject = apps.get(i);
viewHolder.appName.setText(appObject.getApplicationName());
viewHolder.versionNumber.setText(String.valueOf(appObject.getVersionNumber()));
viewHolder.updateDate.setText(String.valueOf(appObject.getLastUdpateTime()));
viewHolder.appIcon.setImageDrawable(appObject.getAppIcon());
viewHolder.appChangelog.setText(appObject.getChangelogText());
viewHolder.favoriteButton.setOnClickListener(new LikeButtonView(mContext));
}
LikeButtonView.java
public class LikeButtonView extends FrameLayout implements View.OnClickListener {
private static final DecelerateInterpolator DECCELERATE_INTERPOLATOR = new DecelerateInterpolator();
private static final AccelerateDecelerateInterpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
private static final OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4);
#Bind(R.id.ivStar)
ImageView ivStar;
private boolean isChecked;
private AnimatorSet animatorSet;
public LikeButtonView(Context context) {
super(context);
init();
}
public LikeButtonView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LikeButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LikeButtonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
LayoutInflater.from(getContext()).inflate(R.layout.view_like_button, this, true);
ButterKnife.bind(this);
setOnClickListener(this);
}
#Override
public void onClick(View v) {
isChecked = !isChecked;
ivStar.setImageResource(isChecked ? R.drawable.ic_star_rate_on : R.drawable.ic_star_rate_off);
if (animatorSet != null) {
animatorSet.cancel();
}
if (isChecked) {
ivStar.animate().cancel();
ivStar.setScaleX(0);
ivStar.setScaleY(0);
animatorSet = new AnimatorSet();
ObjectAnimator starScaleYAnimator = ObjectAnimator.ofFloat(ivStar, ImageView.SCALE_Y, 0.2f, 1f);
starScaleYAnimator.setDuration(350);
starScaleYAnimator.setStartDelay(0);
starScaleYAnimator.setInterpolator(OVERSHOOT_INTERPOLATOR);
ObjectAnimator starScaleXAnimator = ObjectAnimator.ofFloat(ivStar, ImageView.SCALE_X, 0.2f, 1f);
starScaleXAnimator.setDuration(350);
starScaleXAnimator.setStartDelay(0);
starScaleXAnimator.setInterpolator(OVERSHOOT_INTERPOLATOR);
animatorSet.playTogether(
starScaleYAnimator,
starScaleXAnimator
);
animatorSet.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationCancel(Animator animation) {
ivStar.setScaleX(1);
ivStar.setScaleY(1);
}
});
animatorSet.start();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ivStar.animate().scaleX(0.7f).scaleY(0.7f).setDuration(150).setInterpolator(DECCELERATE_INTERPOLATOR);
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
boolean isInside = (x > 0 && x < getWidth() && y > 0 && y < getHeight());
if (isPressed() != isInside) {
setPressed(isInside);
}
break;
case MotionEvent.ACTION_UP:
ivStar.animate().scaleX(1).scaleY(1).setInterpolator(DECCELERATE_INTERPOLATOR);
if (isPressed()) {
performClick();
setPressed(false);
}
break;
}
return true;
}
}

Scaling ImageButton basing on screen size

In my application i can scaling an ImageView using this class
`public class resizeAvatar extends View {
private final Drawable sfondoAvatar;
public resizeAvatar(Context context) {
super(context);
sfondoAvatar = context.getResources().getDrawable(R.drawable.main_voice);
setBackgroundDrawable(sfondoAvatar);
}
public resizeAvatar(Context context, AttributeSet attrs) {
super(context, attrs);
sfondoAvatar = context.getResources().getDrawable(R.drawable.main_voice);
setBackgroundDrawable(sfondoAvatar);
}
public resizeAvatar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
sfondoAvatar = context.getResources().getDrawable(R.drawable.main_voice);
setBackgroundDrawable(sfondoAvatar);
}
#Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * sfondoAvatar.getIntrinsicHeight() / sfondoAvatar.getIntrinsicWidth();
setMeasuredDimension(width, height);
}
}
`
And writing in the layout:
<com.myapp.app.resizeAvatar
android:id="#+id/mainvoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_centerVertical="true"/>
But in this way i can't have the onClick event.. i need do the same but using an ImageButton.. Is there a way?
In the activity where you include this view and in the onCreate method do the following:
resizeAvatar myMainvoice = (resizeAvatar) v.findViewById(R.id.mainvoice);
myMainVoice.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
//place your on click logic here
}
});

Multiple instances of a view object within an android activity

I have two custom view objects that are created within an activity like so.
public class Statistics extends Activity {
GraphWindow graph1;
GraphWindow graph2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.statistics);
graph1 = (GraphWindow) findViewById(R.id.graph1);
graph2 = (GraphWindow) findViewById(R.id.graph2);
...
}
However they seem to be acting as one instance, so a public method to graph1 will also be executed on graph 2. Do I need to initiate each graph view as a new instance somehow? Where would I do this?
EDIT
Here is the (condensed) GraphWindow Class:
public class GraphWindow extends View {
//draw data
public ArrayList<DataPoint> data = new ArrayList<DataPoint>();
//set height
public int graphHeight = 0;
public int indexStart = 0;
public int indexFinish = 0;
public boolean isTouched = false;
public boolean isDraggable = false;
public GraphWindow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public GraphWindow(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GraphWindow(Context context) {
super(context);
}
public void setGraphHeight(int graphHeight) {
this.graphHeight = graphHeight;
}
public void isDraggable(boolean isDraggable) {
this.isDraggable = isDraggable;
}
public void panBox(MotionEvent event) {
rectX = (int)event.getX();
rectW = this.getWidth()/5 + rectX;
this.postInvalidate();
}
public void clearData() {
this.data.clear();
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
...
}
}
In particular the clear data method will operate on both graph1 and graph2.

Categories