I am passing a value to another class, I get the value in another class, but when I am using the value, it shows me 0.
public class MaterialSpinner extends Spinner implements ValueAnimator.AnimatorUpdateListener {
public int widths;
public MaterialSpinner(Context context, int width) {
super(context);
this.widths = width;
// **HERE SHOW ME VALUE FOR EXAMPLE 596**
Log.i("LOG-1", String.valueOf(widths));
init(context, null);
}
#Override
protected void onDraw(Canvas canvas) {
//BUT HERE GET ME 0**
int startX = this.widths;
Log.i("LOG-2", String.valueOf(widths));
}
}
I have other constructors:
public MaterialSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public MaterialSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
Here is my Activity; I pass the value from here to the MaterialSpinner class:
public class StartActivity extends AppCompatActivity {
Context context;
private ArrayAdapter<String> adapter;
int width;
int height;
MaterialSpinner spinner1;
private boolean shown = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
context = this;
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
}
else {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
new MaterialSpinner(context, width);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, ITEMS);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
initSpinnerHintAndFloatingLabel();
}
private void initSpinnerHintAndFloatingLabel() {
spinner1 = (MaterialSpinner) findViewById(R.id.spinner1);
spinner1.setAdapter(adapter);
spinner1.setPaddingSafe(0, 0, 0, 0);
}
}
you are creating an object, you do nothing with it:
new MaterialSpinner(context,width);
in the other function you do this:
spinner1 = (MaterialSpinner) findViewById(R.id.spinner1);
this will inflate the object from the activity_start layout. The easies way would be to create a setWidth() function and call it after you inflated the View
spinner1 = (MaterialSpinner) findViewById(R.id.spinner1);
spinner1.setWidth(width);
EDIT: and remove new MaterialSpinner(context,width); since it does nothing
Related
can a SurfaceView be rendered inside a RecyclerView
what i am trying to do is make a Grid of SurfaceView's
#Keep
public class NativeView {
String TAG = "EglSample";
public static native void nativeOnStart();
public static native void nativeOnResume();
public static native void nativeOnPause();
public static native void nativeOnStop();
// this is part of graphics manager
public native void nativeSetSurface(Surface surface);
View surfaceView = null;
SurfaceHolderCallback surfaceHolderCallback = null;
public NativeView(Context context) {
System.loadLibrary("nativeegl");
surfaceHolderCallback = new SurfaceHolderCallback();
surfaceView = new View(surfaceHolderCallback, context);
}
class View extends SurfaceView {
public View(SurfaceHolder.Callback callback, Context context) {
super(context);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
super(context, attrs, defStyle, defStyleRes);
getHolder().addCallback(callback);
}
}
class SurfaceHolderCallback implements SurfaceHolder.Callback {
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
nativeSetSurface(holder.getSurface());
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
nativeSetSurface(null);
}
}
}
public ViewGroup onViewRequest(Context mContext) {
if (context == null) context = mContext;
if (n == null) n = new NativeView(context);
Log.i(n.TAG, "onViewRequest(Activity, Context)");
// build layout
RelativeLayout rel = new RelativeLayout(context);
rel.addView(n.surfaceView);
n.surfaceView.setOnClickListener(new MyListener());
// set text
TextView text = new TextView(context);
text.setText("Hello World! Try clicking the screen");
text.setTextSize(60f);
text.setTextColor(Color.WHITE);
rel.addView(text);
Log.i(n.TAG, "onCreate()");
// build layout
NativeView.nativeOnStart();
NativeView.nativeOnResume();
return rel;
}
full:
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/java/vst/demo/opengl/addons/cube/main.java
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/java/vst/demo/opengl/addons/cube/NativeView.java
as it renders corrupted in a recycler view (text but no surface view) (you can barely make out the white text but the fact that it is there means the view heirarchy IS being drawn)
(set USE_RECYCLER_VIEW = true)
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/VstManager/src/main/java/vst/manager/VstGrid.java#L29
Boolean USE_RECYCLER_VIEW = false;
public LinearLayout getView() {
// this assumes the first available "*\.addons\.*" package
if (!USE_RECYCLER_VIEW) {
VST pkg = mVstMan.loadPackage(mActivity, mVstMan.getPackages(mActivity)[0].packageName, false);
VST.CLASS vstClass = mVstMan.loadClass(pkg, "main");
Object vstClassInstance = mVstMan.newInstance(vstClass, "main");
// android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
LinearLayout x = new LinearLayout(mActivity);
x.addView((ViewGroup) mVstMan.invokeMethod(
vstClass, vstClassInstance,
"onViewRequest", Context.class,
pkg.activityApplicationContext
)
);
return x;
} else {
if (recyclerViewMain == null)
recyclerViewMain = (LinearLayout) LayoutInflater.from(mActivity.getApplicationContext())
.inflate(R.layout.vst_grid, null, false);
if (recyclerView == null) {
recyclerView = recyclerViewMain
.findViewById(R.id.VstGrid);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
}
if (layoutManager == null) {
// use a linear layout manager
layoutManager = new GridLayoutManager(mActivity, 1);
recyclerView.setLayoutManager(layoutManager);
}
if (mAdapter == null) {
// specify an adapter (see also next example)
mAdapter = new VstGridAdapter(mActivity, mVstMan, mVstUI);
recyclerView.setAdapter(mAdapter);
}
mAdapter.update();
return recyclerViewMain;
}
}
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/VstManager/src/main/java/vst/manager/VstGridAdapter.java#L86
// Create new views (invoked by the layout manager)
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
VST pkg = mVstMan.loadPackage(mActivity, mVstMan.getPackages(mActivity)[0].packageName, false);
VST.CLASS vstClass = mVstMan.loadClass(pkg, "main");
Object vstClassInstance = mVstMan.newInstance(vstClass, "main");
// android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
LinearLayout x = new LinearLayout(mActivity);
x.addView((ViewGroup) mVstMan.invokeMethod(
vstClass, vstClassInstance,
"onViewRequest", Context.class,
pkg.activityApplicationContext
)
);
return new MyViewHolder(x);
}
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/cpp/RotatingSquares/jniapi.cpp
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/cpp/RotatingSquares/renderer.cpp#L153
meanwhile it renders perfectly fine if NOT in a recycler view (leave USE_RECYCLER_VIEW as false)
why?
apparently in order to get it to display i needed to give the view fixed size layout paramaters: mView.setLayoutParams(new ViewGroup.LayoutParams(500, 500));
I have put one recycler view in my project. I want that it will be auto-scroll horizontally. For achieving this I have made one custom class. but I also want that existing functions which I put on my recycler view will also remain.
CustomLinearLayoutManager:
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager (Context context) {
super(context);
}
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
final LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
private static final float MILLISECONDS_PER_INCH = 200f;
#Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return CustomLinearLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
#Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
Home Class
private RecyclerView recyclerViewHeaderSlider;
private HeaderSliderAdapter headerSliderAdapter;
private List<Banner> banners;
banners = new ArrayList<>();
headerSliderAdapter = new HeaderSliderAdapter(getActivity(), banners);
recyclerViewHeaderSlider = view.findViewById(R.id.bannerSlider);
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerViewHeaderSlider);
recyclerViewHeaderSlider.setHasFixedSize(true);
recyclerViewHeaderSlider.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
headerSliderAdapter.setOnClick(this);
recyclerViewHeaderSlider.setAdapter(headerSliderAdapter);
I want to implement my custom linear layout manager with Home class.
You can use Runnable to autoscroll Horizontal RV
public void autoScroll(){
speedScroll = 0;
handler = new Handler();
runnable = new Runnable() {
int count = 0;
#Override
public void run() {
if(count == tickerAdapter.getItemCount())
count = 0;
else {
if(count < tickerAdapter.getItemCount()){
rvTicker.smoothScrollToPosition(++count);
handler.postDelayed(this,speedScroll);
}else {
count = 0;
}
}
}
};
handler.postDelayed(runnable,speedScroll);
}
I already know how to use a custom component in a xml. Now, I'm trying to call one programmatically. I haven't found any tutorial about this so I tried to do it like how we declare a view programmatically. One problem I stumbled upon is that how do I get an AttributeSet that I pass on my constructor? I don't know how I get or create that to pass it for my custom component.
This is my custom component class.
public class CheckOutItem extends ConstraintLayout {
public Context ctx;
public Paint mPaint;
public Rect mRect;
int mSquareColor;
public ImageView imgThumbnail;
public TextView lblAbbrev, lblFullName;
public ConstraintLayout lytMain;
String TAG = "sharePOS";
public CheckOutItem(Context context) {
super(context);
ctx = context;
init(null);
}
public CheckOutItem(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.checkout_item, this);
ctx = context;
init(attrs);
}
public CheckOutItem(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
ctx = context;
init(attrs);
}
private void init(#Nullable AttributeSet set){
//inflate(ctx, R.layout.checkout_item, this);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRect = new Rect();
if(set == null){
return;
}
TypedArray ta = getContext().obtainStyledAttributes(set, R.styleable.CheckOutItem);
this.imgThumbnail = findViewById(R.id.imgItemThumbnail);
this.lblAbbrev = findViewById(R.id.lblItemAbbrevName);
this.lblFullName = findViewById(R.id.lblItemFullName);
this.lytMain = findViewById(R.id.lytMain);
this.lblAbbrev.setText(ta.getText(R.styleable.CheckOutItem_abbrevText));
this.lblAbbrev.setTextSize(ta.getDimension(R.styleable.CheckOutItem_abbrevTextSize, 1f));
this.lblAbbrev.setTextColor(ta.getColor(R.styleable.CheckOutItem_abbrevTextColor, Color.BLACK));
this.lblFullName.setText(ta.getText(R.styleable.CheckOutItem_fullNameText));
this.lblFullName.setTextSize(ta.getDimension(R.styleable.CheckOutItem_fullNameTextSize, 1f));
this.lblFullName.setTextColor(ta.getColor(R.styleable.CheckOutItem_fullNameTextColor, Color.BLACK));
this.lblFullName.setBackgroundColor(ta.getColor(R.styleable.CheckOutItem_fullNameBackgroundColor, Color.WHITE));
this.lytMain.setBackgroundColor(ta.getColor(R.styleable.CheckOutItem_mainBackgroundColor, Color.LTGRAY));
this.lytMain.setBackground(ta.getDrawable(R.styleable.CheckOutItem_mainBackgroundDrawable));
ta.recycle();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mRect.left = 0;
mRect.right = getWidth();
mRect.top = 0;
mRect.bottom = getHeight();
Log.d(TAG, "rect: " + mRect);
canvas.drawRect(mRect, mPaint);
}
}
UPDATE:
How do I set a margin in the custom component? Regular LayoutParams with setMargins() doesn't seem to work.
the goal is to create 5x5 grid buttons and fill the screen
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL); //Can also be done in xml by android:orientation="vertical"
int widthOfCell = (int) squareSize(screenWidth().widthPixels, screenWidth().heightPixels, 9);
for (int i = 0; i < 5; i++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 5; j++) {
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(0, 0, 1.0f);
DynamicSquareLayout btnTag = new DynamicSquareLayout(this);
btnTag.setLayoutParams(param);
btnTag.setText("Button " + (j + 1 + (i * 4 )));
btnTag.setId(j + 1 + (i * 4));
row.addView(btnTag);
}
layout.addView(row);
}
setContentView(layout);
}
class DynamicSquareLayout extends Button {
public DynamicSquareLayout(Context context) {
super(context);
}
public DynamicSquareLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public DynamicSquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
int size = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(size, size);
}
}
However it doesn't fill all screen , how to modify it to fill the screen although the buttons are squares
You need to set
row.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f)); as your row layout params so that all 5 rows get evenly distributed in the layout. Here's the full code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
LinearLayout layout = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
layout.setOrientation(LinearLayout.VERTICAL); //Can also be done in xml by android:orientation="vertical"
int widthOfCell = 20; //(int) squareSize(screenWidth().widthPixels, screenWidth().heightPixels, 9);
for (int i = 0; i < 5; i++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
for (int j = 0; j < 5; j++) {
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(0, 0, 1.0f);
DynamicSquareLayout btnTag = new DynamicSquareLayout(this);
btnTag.setLayoutParams(param);
btnTag.setText("Button " + (j + 1 + (i * 4 )));
btnTag.setId(j + 1 + (i * 4));
row.addView(btnTag);
}
layout.addView(row);
}
layout.setLayoutParams(params);
setContentView(layout);
}
class DynamicSquareLayout extends android.support.v7.widget.AppCompatButton {
public DynamicSquareLayout(Context context) {
super(context);
}
public DynamicSquareLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public DynamicSquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
int size = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(size, size);
}
}
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;
}
}