How to change text color of Segmented Controls (if not selected), see below images:
I am getting like this (text in white color):
And want to design this (text in blue color):
Why i am getting space between 3 and 4 button ?
XML:
<com.om.go.widget.SegmentedButton
android:id="#+id/segmented"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
myapp:gradientColorOnStart="#ffffff"
myapp:gradientColorOnEnd="#ffffff"
myapp:gradientColorOffStart="#016de3"
myapp:gradientColorOffEnd="#016de3"
myapp:textStyle="#style/TextViewStyleHeaderButtonBlue"
myapp:strokeColor="#016de3"
myapp:strokeWidth="1dip"
myapp:cornerRadius="4dip"
myapp:btnPaddingTop="7dip"
myapp:btnPaddingBottom="7dip"
/>
SegmentedButton.java:-
public class SegmentedButton extends LinearLayout {
private StateListDrawable mBgLeftOn;
private StateListDrawable mBgRightOn;
private StateListDrawable mBgCenterOn;
private StateListDrawable mBgLeftOff;
private StateListDrawable mBgRightOff;
private StateListDrawable mBgCenterOff;
private int mSelectedButtonIndex = 0;
private List<String> mButtonTitles = new ArrayList<String>();
private int mColorOnStart;
private int mColorOnEnd;
private int mColorOffStart;
private int mColorOffEnd;
private int mColorSelectedStart;
private int mColorSelectedEnd;
private int mColorStroke;
private int mStrokeWidth;
private int mCornerRadius;
private int mTextStyle;
private int mBtnPaddingTop;
private int mBtnPaddingBottom;
private OnClickListenerSegmentedButton mOnClickListenerExternal;
public SegmentedButton(Context context) {
super(context);
}
public SegmentedButton(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SegmentedButton, 0, 0);
CharSequence btnText1 = a.getString(R.styleable.SegmentedButton_btnText1);
CharSequence btnText2 = a.getString(R.styleable.SegmentedButton_btnText2);
if (btnText1 != null) {
mButtonTitles.add(btnText1.toString());
}
if (btnText2 != null) {
mButtonTitles.add(btnText2.toString());
}
mColorOnStart = a.getColor(R.styleable.SegmentedButton_gradientColorOnStart, 0xFF0000);
mColorOnEnd = a.getColor(R.styleable.SegmentedButton_gradientColorOnEnd, 0xFF0000);
mColorOffStart = a.getColor(R.styleable.SegmentedButton_gradientColorOffStart, 0xFF0000);
mColorOffEnd = a.getColor(R.styleable.SegmentedButton_gradientColorOffEnd, 0xFF0000);
mColorStroke = a.getColor(R.styleable.SegmentedButton_strokeColor, 0xFF0000);
mColorSelectedEnd = a.getColor(R.styleable.SegmentedButton_gradientColorSelectedEnd, 0xFF0000);
mColorSelectedStart = a.getColor(R.styleable.SegmentedButton_gradientColorSelectedStart, 0xFF0000);
mStrokeWidth = a.getDimensionPixelSize(R.styleable.SegmentedButton_strokeWidth, 1);
mCornerRadius = a.getDimensionPixelSize(R.styleable.SegmentedButton_cornerRadius, 4);
mTextStyle = a.getResourceId(R.styleable.SegmentedButton_textStyle, -1);
mBtnPaddingTop = a.getDimensionPixelSize(R.styleable.SegmentedButton_btnPaddingTop, 0);
mBtnPaddingBottom = a.getDimensionPixelSize(R.styleable.SegmentedButton_btnPaddingBottom, 0);
a.recycle();
buildDrawables(mColorOnStart, mColorOnEnd, mColorOffStart, mColorOffEnd,
mColorSelectedStart, mColorSelectedEnd, mCornerRadius, mColorStroke,
mStrokeWidth);
if (mButtonTitles.size() > 0) {
_addButtons(new String[mButtonTitles.size()]);
}
}
public void clearButtons() {
removeAllViews();
}
public void addButtons(String ... titles) {
_addButtons(titles);
}
#SuppressWarnings("deprecation")
private void _addButtons(String[] titles) {
for (int i = 0; i < titles.length; i++) {
Button button = new Button(getContext());
button.setText(titles[i]);
button.setTag(new Integer(i));
button.setOnClickListener(mOnClickListener);
if (mTextStyle != -1) {
button.setTextAppearance(getContext(), mTextStyle);
}
if (titles.length == 1) {
// Don't use a segmented button with one button.
return;
} else if (titles.length == 2) {
if (i == 0) {
button.setBackgroundDrawable(mBgLeftOff);
} else {
button.setBackgroundDrawable(mBgRightOn);
}
} else {
if (i == 0) {
button.setBackgroundDrawable(mBgLeftOff);
} else if (i == titles.length-1) {
button.setBackgroundDrawable(mBgRightOn);
} else {
button.setBackgroundDrawable(mBgCenterOn);
}
}
LinearLayout.LayoutParams llp =
new LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.WRAP_CONTENT,
1);
addView(button, llp);
button.setPadding(0, mBtnPaddingTop, 0, mBtnPaddingBottom);
}
}
private void buildDrawables(int colorOnStart,
int colorOnEnd,
int colorOffStart,
int colorOffEnd,
int colorSelectedStart,
int colorSelectedEnd,
float crad,
int strokeColor,
int strokeWidth)
{
// top-left, top-right, bottom-right, bottom-left
float[] radiiLeft = new float[] {
crad, crad, 0, 0, 0, 0, crad, crad
};
float[] radiiRight = new float[] {
0, 0, crad, crad, crad, crad, 0, 0
};
float[] radiiCenter = new float[] {
0, 0, 0, 0, 0, 0, 0, 0
};
GradientDrawable leftOn = buildGradientDrawable(colorOnStart, colorOnEnd, strokeWidth, strokeColor);
leftOn.setCornerRadii(radiiLeft);
GradientDrawable leftOff = buildGradientDrawable(colorOffStart, colorOffEnd, strokeWidth, strokeColor);
leftOff.setCornerRadii(radiiLeft);
GradientDrawable leftSelected = buildGradientDrawable(colorSelectedStart, colorSelectedEnd, strokeWidth, strokeColor);
leftSelected.setCornerRadii(radiiLeft);
GradientDrawable rightOn = buildGradientDrawable(colorOnStart, colorOnEnd, strokeWidth, strokeColor);
rightOn.setCornerRadii(radiiRight);
GradientDrawable rightOff = buildGradientDrawable(colorOffStart, colorOffEnd, strokeWidth, strokeColor);
rightOff.setCornerRadii(radiiRight);
GradientDrawable rightSelected = buildGradientDrawable(colorSelectedStart, colorSelectedEnd, strokeWidth, strokeColor);
rightSelected.setCornerRadii(radiiRight);
GradientDrawable centerOn = buildGradientDrawable(colorOnStart, colorOnEnd, strokeWidth, strokeColor);
centerOn.setCornerRadii(radiiCenter);
GradientDrawable centerOff = buildGradientDrawable(colorOffStart, colorOffEnd, strokeWidth, strokeColor);
centerOff.setCornerRadii(radiiCenter);
GradientDrawable centerSelected = buildGradientDrawable(colorSelectedStart, colorSelectedEnd, strokeWidth, strokeColor);
centerSelected.setCornerRadii(radiiCenter);
List<int[]> onStates = buildOnStates();
List<int[]> offStates = buildOffStates();
mBgLeftOn = new StateListDrawable();
mBgRightOn = new StateListDrawable();
mBgCenterOn = new StateListDrawable();
mBgLeftOff = new StateListDrawable();
mBgRightOff = new StateListDrawable();
mBgCenterOff = new StateListDrawable();
for (int[] it : onStates) {
mBgLeftOn.addState(it, leftSelected);
mBgRightOn.addState(it, rightSelected);
mBgCenterOn.addState(it, centerSelected);
mBgLeftOff.addState(it, leftSelected);
mBgRightOff.addState(it, rightSelected);
mBgCenterOff.addState(it, centerSelected);
}
for (int[] it : offStates) {
mBgLeftOn.addState(it, leftOn);
mBgRightOn.addState(it, rightOn);
mBgCenterOn.addState(it, centerOn);
mBgLeftOff.addState(it, leftOff);
mBgRightOff.addState(it, rightOff);
mBgCenterOff.addState(it, centerOff);
}
}
private List<int[]> buildOnStates() {
List<int[]> res = new ArrayList<int[]>();
res.add(new int[] {
android.R.attr.state_focused, android.R.attr.state_enabled});
res.add(new int[] {
android.R.attr.state_focused, android.R.attr.state_selected, android.R.attr.state_enabled});
res.add(new int[] {
android.R.attr.state_pressed});
return res;
}
private List<int[]> buildOffStates() {
List<int[]> res = new ArrayList<int[]>();
res.add(new int[] {
android.R.attr.state_enabled});
res.add(new int[] {
android.R.attr.state_selected, android.R.attr.state_enabled});
return res;
}
private GradientDrawable buildGradientDrawable(int colorStart, int colorEnd, int strokeWidth, int strokeColor) {
GradientDrawable gd = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[] { colorStart, colorEnd });
gd.setShape(GradientDrawable.RECTANGLE);
gd.setStroke(strokeWidth, strokeColor);
return gd;
}
private OnClickListener mOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
Button btnNext = (Button)v;
int btnNextIndex = ((Integer)btnNext.getTag()).intValue();
if (btnNextIndex == mSelectedButtonIndex) {
return;
}
handleStateChange(mSelectedButtonIndex, btnNextIndex);
if (mOnClickListenerExternal != null) {
mOnClickListenerExternal.onClick(mSelectedButtonIndex);
}
}
};
#SuppressWarnings("deprecation")
private void handleStateChange(int btnLastIndex, int btnNextIndex) {
int count = getChildCount();
Button btnLast = (Button)getChildAt(btnLastIndex);
Button btnNext = (Button)getChildAt(btnNextIndex);
if (count < 3) {
if (btnLastIndex == 0) {
btnLast.setBackgroundDrawable(mBgLeftOn);
} else {
btnLast.setBackgroundDrawable(mBgRightOn);
}
if (btnNextIndex == 0) {
btnNext.setBackgroundDrawable(mBgLeftOff);
} else {
btnNext.setBackgroundDrawable(mBgRightOff);
}
} else {
if (btnLastIndex == 0) {
btnLast.setBackgroundDrawable(mBgLeftOn);
} else if (btnLastIndex == count-1) {
btnLast.setBackgroundDrawable(mBgRightOn);
} else {
btnLast.setBackgroundDrawable(mBgCenterOn);
}
if (btnNextIndex == 0) {
btnNext.setBackgroundDrawable(mBgLeftOff);
} else if (btnNextIndex == count-1) {
btnNext.setBackgroundDrawable(mBgRightOff);
} else {
btnNext.setBackgroundDrawable(mBgCenterOff);
}
}
btnLast.setPadding(0, mBtnPaddingTop, 0, mBtnPaddingBottom);
btnNext.setPadding(0, mBtnPaddingTop, 0, mBtnPaddingBottom);
mSelectedButtonIndex = btnNextIndex;
}
public int getSelectedButtonIndex() {
return mSelectedButtonIndex;
}
public void setPushedButtonIndex(int index) {
handleStateChange(mSelectedButtonIndex, index);
}
public void setOnClickListener(OnClickListenerSegmentedButton listener) {
mOnClickListenerExternal = listener;
}
public interface OnClickListenerSegmentedButton {
public void onClick(int index);
}
}
Related
Getting error while creating custom view for shimmer layout.
Reference: https://github.com/team-supercharge/ShimmerLayout/blob/master/shimmerlayout/src/main/java/io/supercharge/shimmerlayout/ShimmerLayout.java
Error: System.NotSupportedException: Could not activate JNI Handle 0xbeb6ade8 (key_handle 0xbc32e58) of Java type 'md5f5fa8eda1f5ef6033c7dd372483fe62e/ShimmerSplitsLayout' as managed type 'JammberSplits.Droid.CustomControls.ShimmerSplitsLayout'.
internal class ViewTreeObserverListner : Java.Lang.Object, ViewTreeObserver.IOnPreDrawListener
{
ViewTreeObserver _viewTreeObserver;
ShimmerSplitsLayout _shimmerLayout;
public ViewTreeObserverListner(ViewTreeObserver viewTreeObserver, ShimmerSplitsLayout shimmerLayout)
{
_viewTreeObserver = viewTreeObserver;
_shimmerLayout = shimmerLayout;
}
public bool OnPreDraw()
{
_viewTreeObserver.RemoveOnPreDrawListener(this);
//_shimmerLayout.startShimmerAnimation();
return true;
}
}
internal class ShimmerAnimation : Java.Lang.Object, ValueAnimator.IAnimatorUpdateListener
{
int _animationFromX;
public ShimmerAnimation(int animationFromX)
{
_animationFromX = animationFromX;
}
public void OnAnimationUpdate(ValueAnimator animation)
{
ShimmerSplitsLayout.maskOffsetX = _animationFromX + (int)animation.AnimatedValue;
}
}
public class ShimmerSplitsLayout : FrameLayout
{
private static int DEFAULT_ANIMATION_DURATION = 1500;
private static byte DEFAULT_ANGLE = 20;
private static byte MIN_ANGLE_VALUE = Convert.ToByte(-45);
private static byte MAX_ANGLE_VALUE = 45;
private static byte MIN_MASK_WIDTH_VALUE = 0;
private static byte MAX_MASK_WIDTH_VALUE = 1;
private static byte MIN_GRADIENT_CENTER_COLOR_WIDTH_VALUE = 0;
private static byte MAX_GRADIENT_CENTER_COLOR_WIDTH_VALUE = 1;
public static int maskOffsetX;
private Rect maskRect;
private Paint gradientTexturePaint;
private ValueAnimator maskAnimator;
private Bitmap localMaskBitmap;
private Bitmap maskBitmap;
private Canvas canvasForShimmerMask;
private bool isAnimationReversed;
private bool isAnimationStarted;
private bool autoStart;
private int shimmerAnimationDuration;
private int shimmerColor;
private int shimmerAngle;
private float maskWidth;
private float gradientCenterColorWidth;
private ViewTreeObserver.IOnPreDrawListener startAnimationPreDrawListener;
public ShimmerSplitsLayout(Context context) : base(context)
{
}
public ShimmerSplitsLayout(Context context, IAttributeSet attrs) : base(context, attrs)
{
Initialize(context, attrs);
}
public ShimmerSplitsLayout(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
Initialize(context, attrs);
}
public ShimmerSplitsLayout(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
{
Initialize(context, attrs);
}
protected ShimmerSplitsLayout(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
private void Initialize(Context context, IAttributeSet attrs)
{
SetWillNotDraw(false);
TypedArray a = context.Theme.ObtainStyledAttributes(
attrs,
Resource.Styleable.ShimmerLayout,
0, 0);
try
{
shimmerAngle = a.GetInteger(Resource.Styleable.ShimmerLayout_shimmer_angle, DEFAULT_ANGLE);
shimmerAnimationDuration = a.GetInteger(Resource.Styleable.ShimmerLayout_shimmer_animation_duration, DEFAULT_ANIMATION_DURATION);
shimmerColor = a.GetColor(Resource.Styleable.ShimmerLayout_shimmer_color, Resources.GetColor(Resource.Color.shimmer_color));
autoStart = a.GetBoolean(Resource.Styleable.ShimmerLayout_shimmer_auto_start, false);
maskWidth = a.GetFloat(Resource.Styleable.ShimmerLayout_shimmer_mask_width, 0.5F);
gradientCenterColorWidth = a.GetFloat(Resource.Styleable.ShimmerLayout_shimmer_gradient_center_color_width, 0.1F);
isAnimationReversed = a.GetBoolean(Resource.Styleable.ShimmerLayout_shimmer_reverse_animation, false);
}
finally
{
a.Recycle();
}
setMaskWidth(maskWidth);
setGradientCenterColorWidth(gradientCenterColorWidth);
setShimmerAngle(shimmerAngle);
enableForcedSoftwareLayerIfNeeded();
if (autoStart && Visibility == ViewStates.Visible)
{
startShimmerAnimation();
}
}
protected override void OnDetachedFromWindow()
{
resetShimmering();
base.OnDetachedFromWindow();
}
private void resetIfStarted()
{
if (isAnimationStarted)
{
resetShimmering();
startShimmerAnimation();
}
}
protected override void DispatchDraw(Canvas canvas)
{
if (!isAnimationStarted || Width <= 0 || Height <= 0)
{
base.DispatchDraw(canvas);
}
else
{
dispatchDrawShimmer(canvas);
}
}
private void dispatchDrawShimmer(Canvas canvas)
{
localMaskBitmap = getMaskBitmap();
if (localMaskBitmap == null)
{
return;
}
if (canvasForShimmerMask == null)
{
canvasForShimmerMask = new Canvas(localMaskBitmap);
}
canvasForShimmerMask.DrawColor(Color.Transparent, PorterDuff.Mode.Clear);
canvasForShimmerMask.Save();
canvasForShimmerMask.Translate(-maskOffsetX, 0);
base.DispatchDraw(canvasForShimmerMask);
canvasForShimmerMask.Restore();
drawShimmer(canvas);
localMaskBitmap = null;
}
private void resetShimmering()
{
if (maskAnimator != null)
{
maskAnimator.End();
maskAnimator.RemoveAllUpdateListeners();
}
maskAnimator = null;
gradientTexturePaint = null;
isAnimationStarted = false;
releaseBitMaps();
}
private void drawShimmer(Canvas destinationCanvas)
{
createShimmerPaint();
destinationCanvas.Save();
destinationCanvas.Translate(maskOffsetX, 0);
destinationCanvas.DrawRect(maskRect.Left, 0, maskRect.Width(), maskRect.Height(), gradientTexturePaint);
destinationCanvas.Restore();
}
public void startShimmerAnimation()
{
if (isAnimationStarted)
{
return;
}
if (Width == 0)
{
startAnimationPreDrawListener = new ViewTreeObserverListner(ViewTreeObserver, this);
ViewTreeObserver.AddOnPreDrawListener(startAnimationPreDrawListener);
return;
}
Animator animator = getShimmerAnimation();
animator.Start();
isAnimationStarted = true;
}
private void releaseBitMaps()
{
canvasForShimmerMask = null;
if (maskBitmap != null)
{
maskBitmap.Recycle();
maskBitmap = null;
}
}
private Bitmap getMaskBitmap()
{
if (maskBitmap == null)
{
maskBitmap = createBitmap(maskRect.Width(), Height);
}
return maskBitmap;
}
private void createShimmerPaint()
{
if (gradientTexturePaint != null)
{
return;
}
int edgeColor = reduceColorAlphaValueToZero(shimmerColor);
float shimmerLineWidth = Width / 2 * maskWidth;
float yPosition = (0 <= shimmerAngle) ? Height : 0;
LinearGradient gradient = new LinearGradient(
0, yPosition,
(float)Math.Cos(degreesToRadians(shimmerAngle)) * shimmerLineWidth,
yPosition + (float)Math.Sin(degreesToRadians(shimmerAngle)) * shimmerLineWidth,
new int[] { edgeColor, shimmerColor, shimmerColor, edgeColor },
getGradientColorDistribution(),
Shader.TileMode.Clamp);
BitmapShader maskBitmapShader = new BitmapShader(localMaskBitmap, Shader.TileMode.Clamp, Shader.TileMode.Clamp);
ComposeShader composeShader = new ComposeShader(gradient, maskBitmapShader, PorterDuff.Mode.DstIn);
gradientTexturePaint = new Paint();
gradientTexturePaint.AntiAlias = (true);
gradientTexturePaint.Dither = (true);
gradientTexturePaint.FilterBitmap = (true);
gradientTexturePaint.SetShader(composeShader);
}
public void stopShimmerAnimation()
{
if (startAnimationPreDrawListener != null)
{
ViewTreeObserver.RemoveOnPreDrawListener(startAnimationPreDrawListener);
}
resetShimmering();
}
private Animator getShimmerAnimation()
{
if (maskAnimator != null)
{
return maskAnimator;
}
if (maskRect == null)
{
maskRect = calculateBitmapMaskRect();
}
int animationToX = Width;
int animationFromX;
if (Width > maskRect.Width())
{
animationFromX = -animationToX;
}
else
{
animationFromX = -maskRect.Width();
}
int shimmerBitmapWidth = maskRect.Width();
int shimmerAnimationFullLength = animationToX - animationFromX;
maskAnimator = isAnimationReversed ? ValueAnimator.OfInt(shimmerAnimationFullLength, 0)
: ValueAnimator.OfInt(0, shimmerAnimationFullLength);
maskAnimator.SetDuration(shimmerAnimationDuration);
maskAnimator.RepeatCount = (ObjectAnimator.Infinite);
maskAnimator.AddUpdateListener(new ShimmerAnimation(animationFromX));
return maskAnimator;
}
private Bitmap createBitmap(int width, int height)
{
try
{
return Bitmap.CreateBitmap(width, height, Bitmap.Config.Alpha8);
}
catch (OutOfMemoryException e)
{
return null;
}
}
private int getColor(int id)
{
if (Build.VERSION.SdkInt >= Build.VERSION_CODES.M)
{
return Context.GetColor(id);
}
else
{
//noinspection deprecation
return Resources.GetColor(id);
}
}
private int reduceColorAlphaValueToZero(int actualColor)
{
return Color.Argb(0, actualColor, actualColor, actualColor);
}
private Rect calculateBitmapMaskRect()
{
return new Rect(0, 0, calculateMaskWidth(), Height);
}
private int calculateMaskWidth()
{
double shimmerLineBottomWidth = (Width / 2 * maskWidth) / Math.Cos(degreesToRadians(Math.Abs(shimmerAngle)));
double shimmerLineRemainingTopWidth = Height * Math.Tan(degreesToRadians(Math.Abs(shimmerAngle)));
return (int)(shimmerLineBottomWidth + shimmerLineRemainingTopWidth);
}
public double degreesToRadians(double degrees)
{
return (degrees * Math.PI) / 180;
}
private float[] getGradientColorDistribution()
{
float[] colorDistribution = new float[4];
colorDistribution[0] = 0;
colorDistribution[3] = 1;
colorDistribution[1] = 0.5F - gradientCenterColorWidth / 2F;
colorDistribution[2] = 0.5F + gradientCenterColorWidth / 2F;
return colorDistribution;
}
private void enableForcedSoftwareLayerIfNeeded()
{
if (Build.VERSION.SdkInt <= Build.VERSION_CODES.JellyBean)
{
SetLayerType(LayerType.Software, null);
}
}
public void setShimmerColor(int shimmerColor)
{
this.shimmerColor = shimmerColor;
resetIfStarted();
}
public void setShimmerAnimationDuration(int durationMillis)
{
this.shimmerAnimationDuration = durationMillis;
resetIfStarted();
}
public void setAnimationReversed(bool animationReversed)
{
this.isAnimationReversed = animationReversed;
resetIfStarted();
}
private void setShimmerAngle(int shimmerAngle)
{
if (shimmerAngle < MIN_ANGLE_VALUE || MAX_ANGLE_VALUE < shimmerAngle)
{
}
this.shimmerAngle = shimmerAngle;
resetIfStarted();
}
private void setGradientCenterColorWidth(float gradientCenterColorWidth)
{
if (gradientCenterColorWidth <= MIN_GRADIENT_CENTER_COLOR_WIDTH_VALUE
|| MAX_GRADIENT_CENTER_COLOR_WIDTH_VALUE <= gradientCenterColorWidth)
{
}
this.gradientCenterColorWidth = gradientCenterColorWidth;
resetIfStarted();
}
private void setMaskWidth(float maskWidth)
{
if (maskWidth <= MIN_MASK_WIDTH_VALUE || MAX_MASK_WIDTH_VALUE < maskWidth)
{
}
this.maskWidth = maskWidth;
resetIfStarted();
}
}
Check your .axml file. You should use lower case letters for the namespace and camelcase for the class name in the axml file (as shown in https://stackoverflow.com/a/54932494/9335822).
Change your xml file like:
<jammbersplits.droid.customcontrols.ShimmerSplitsLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/shimmerLayout"
... />
I get a problem with converting code from native Android JAVA code to Xamarin C# Android code:
I have a class ThumbnailStrip:
How to set Orientation
LayOutParameters
OnClickListener
class ThumbnailStrip extends FrameLayout {
Context con;
Rotator rotator;
CustomImageView images;
int count;
Bitmap bitmap;
double viewHeight, viewWidth;
private boolean isDown;
private float X,Y,dX,dY,diffX,diffY;
private boolean NEXT,PREVIOUS;
LinearLayout thumbLayout;
public ThumbnailStrip(Context context, SfRotator _imageSlider, double height, double width) {
super(context);
con = context;
rotator = _imageSlider;
thumbLayout = new LinearLayout(context);
if (rotator.getNavigationStripPosition() == NavigationStripPosition.Top || rotator.getNavigationStripPosition() == NavigationStripPosition.Bottom)
thumbLayout.setOrientation(LinearLayout.HORIZONTAL);
else
thumbLayout.setOrientation(LinearLayout.VERTICAL);
if (thumbLayout.getOrientation() == LinearLayout.HORIZONTAL) {
viewHeight = height-10;
viewWidth = width / 5;
} else {
viewHeight = height / 5;
viewWidth = width-10;
}
createThumbnails(con);
}
Timer thumbTimer;boolean thumbStart,isDynamicView;
public ThumbnailStrip(Context context, AttributeSet attrs) {
super(context, attrs);
}
private void createThumbnails(Context con) {
if (rotator.getDataSource() != null) {
count = rotator.getDataSource().size();
for (int i = 0; i < count; i++) {
View view;
if(rotator.getAdapter()!=null && rotator.getAdapter().getThumbnailView(rotator,i)!=null) {
view = rotator.getAdapter().getThumbnailView(rotator, i);
isDynamicView = true;
}
else {
if(rotator.getDataSource().get(i).getContent()!=null) {
view = rotator.getDataSource().get(i).getContent();
isDynamicView = false;
}
else
{
ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
int resID = getResources().getIdentifier(rotator.getDataSource().get(i).getImageContent(), "drawable", getContext().getPackageName());
bitmap = BitmapFactory.decodeResource(getResources(), resID);
imageView.setImageBitmap(bitmap);
view=imageView;
isDynamicView = false;
}
}
view.setLayoutParams(new ViewGroup.LayoutParams(rotator.getWidth(),rotator.getHeight()));
images = new CustomImageView(con,view , (float) viewWidth, (float) viewHeight,isDynamicView);
images.setClickable(true);
images.setPadding(6, 0, 0, 0);
if(thumbLayout.getOrientation()==LinearLayout.VERTICAL) {
images.setPadding(6, 6, 0, 0);
}
images.setIndex(i);
if (i == rotator.getSelectedIndex()) {
images.setSelectedImage(true);
}
images.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
LayoutParams itemLayout;
itemLayout = new LayoutParams((int) viewWidth, (int) (viewHeight), Gravity.CENTER_VERTICAL);
itemLayout.setMargins(6, 6, 0, 0);
thumbLayout.addView(images, itemLayout);
//Especially I don't know how to set OnCliCkListener,Please help me with a solution.
images.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (rotator.isEnableAutoPlay()) {
rotator.isAnimationinteracted = true;
}
final CustomImageView imgView = (CustomImageView) v;
if (imgView.getIndex() > rotator.getSelectedIndex())
rotator.setPlayDirection(PlayDirection.MoveBackward);
else
rotator.setPlayDirection(PlayDirection.MoveForward);
if (imgView.getIndex() != rotator.getSelectedIndex()) {
rotator.setSelectedIndex((imgView).getIndex());
if (rotator.isEnableAutoPlay()) {
thumbStart = true;
}
}
}
});
}
this.addView(thumbLayout);
}
}
}
Pls, Help me to convert.
Layout Parameters in Xamarin is like this:
LinearLayout linear = new LinearLayout(this);
ImageView image = new ImageView(this);
LinearLayout.LayoutParams linearLayoutParams = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.FillParent,
LinearLayout.LayoutParams.FillParent);
linear.LayoutParameters = linearLayoutParams;
Cheking Orientation like this:
if(linear.Orientation == Orientation.Horizontal){
}
onCLick Listener in Java will convert into Events like this
image.Click += (sender, e) => {
};
images.Click += (sender, e) =>
{
if (rotator.isEnableAutoPlay())
{
rotator.isAnimationinteracted = true;
}
CustomImageView imgView = (CustomImageView)view;
if (imgView.getIndex() > rotator.getSelectedIndex())
rotator.playDirection = PlayDirection.MoveBackward;
else
rotator.playDirection = PlayDirection.MoveForward;
if (imgView.getIndex() != rotator.getSelectedIndex())
{
rotator.setSelectedIndex((imgView).getIndex());
if (rotator.isEnableAutoPlay())
{
thumbStart = true;
}
}
};
I am Using SelectableTextview in my e-book app where i want to highlight any text from the book. The text is being highlighted by SelectableTextViewer class, and i am saving the selected text in database. Now i want when the user open the e-book next time the same text should be highlighted as it is. But there is no method of setting selected text. How can i solve this problem. Please help me
SelectableTextviewer.java
public class SelectableTextViewer extends RelativeLayout {
private ImageView imgStartSelect;
public static int mStartSelect = -1;
private ImageView imgEndSelect;
public static int mEndSelect = -1;
private int mImgWidth = 40;
private int mImgHeight = 50;
private TextView textView;
private View mCurrentControlFocused;
public static interface ISelectableTextViewerListener {
public void updateSelection(SelectableTextViewer selectableTextViewer);
public void endSelectingText(SelectableTextViewer selectableTextViewer,
String selectedText);
public void stopSelectingText(
SelectableTextViewer selectableTextViewer, String selectedText);
}
private ISelectableTextViewerListener selectableTextViewerListener;
public static BackgroundColorSpan spanBackgroundColored;
public void setSelectableTextViewerListener(
ISelectableTextViewerListener selectableTextViewerListener) {
this.selectableTextViewerListener = selectableTextViewerListener;
}
public SelectableTextViewer(Context context) {
super(context);
if (!isInEditMode()) {
this.initControls();
}
}
public SelectableTextViewer(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
this.initControls();
}
}
public SelectableTextViewer(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
if (!isInEditMode()) {
this.initControls();
}
}
private void initControls() {
this.spanBackgroundColored = new BackgroundColorSpan(Color.YELLOW);
this.textView = new TextView(getContext());
this.addView(textView);
this.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
showSelectionControls();
int[] location = { 0, 0 };
getLocationOnScreen(location);
System.out.println("getLocationOnScreen:" + location[0] + "\t"
+ location[1]);
return false;
}
});
this.createImgControllersForSelection();
}
protected void disallowIntercept(Boolean disallowIntercept) {
this.getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
}
protected void createImgControllersForSelection() {
this.imgStartSelect = new ImageView(getContext());
this.imgEndSelect = new ImageView(getContext());
this.imgStartSelect.setImageResource(R.drawable.cursor);
this.imgEndSelect.setImageResource(R.drawable.cursor);
this.addView(imgStartSelect, mImgWidth, mImgHeight);
this.addView(imgEndSelect, mImgWidth, mImgHeight);
OnClickListener onClickForChangeFocus = new OnClickListener() {
#Override
public void onClick(View v) {
mCurrentControlFocused = v;
}
};
this.imgEndSelect.setOnClickListener(onClickForChangeFocus);
this.imgStartSelect.setOnClickListener(onClickForChangeFocus);
OnTouchListener onTouchSelectionControl = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
disallowIntercept(true);
mCurrentControlFocused = v;
int eid = event.getAction();
switch (eid) {
case MotionEvent.ACTION_MOVE:
int[] location = { 0, 0 };
getLocationOnScreen(location);
LayoutParams mParams = (LayoutParams) v
.getLayoutParams();
int x = (int) event.getRawX();
int y = (int) event.getRawY();
// + insideScrollView.getScrollY();
mParams.leftMargin = x - mImgWidth / 2 - location[0];
if (x <= 0) {
mParams.leftMargin = mImgWidth;
} else if (x > (getMeasuredWidth() - mImgWidth)) {
mParams.leftMargin = getMeasuredWidth() - mImgWidth;
}
// TODO Must calculate all padding control
mParams.topMargin = (int) (y - (location[1] + mImgHeight * 1.5f));
if (mParams.topMargin <= 1) {
mParams.topMargin = 1;
}
v.setLayoutParams(mParams);
updateSelectionByMovementImgControls(mParams.leftMargin,
mParams.topMargin);
break;
case MotionEvent.ACTION_UP:
if (selectableTextViewerListener != null) {
selectableTextViewerListener.endSelectingText(
SelectableTextViewer.this, getSelectedText());
}
break;
default:
disallowIntercept(false);
break;
}
return true;
}
};
this.imgEndSelect.setOnTouchListener(onTouchSelectionControl);
this.imgStartSelect.setOnTouchListener(onTouchSelectionControl);
this.imgEndSelect.setVisibility(View.GONE);
this.imgStartSelect.setVisibility(View.GONE);
}
public void updateSelectionByMovementImgControls(int x, int y) {
if (mCurrentControlFocused.equals(imgStartSelect)) {
this.mStartSelect = getOffsetByCoordinates(x + mImgWidth / 2, y);
} else if (mCurrentControlFocused.equals(imgEndSelect)) {
this.mEndSelect = getOffsetByCoordinates(x + mImgWidth / 2, y);
}
updateSelectionSpan();
}
protected Layout updateSelectionSpan() {
Layout retLayout = this.textView.getLayout();
if (this.mStartSelect > -1 && this.mEndSelect > -1) {
if (this.mStartSelect > this.mEndSelect) {
int temp = mEndSelect;
this.mEndSelect = mStartSelect;
this.mStartSelect = temp;
showSelectionControls();
}
SpannedString spannable = (SpannedString) this.textView.getText();
SpannableStringBuilder ssb = new SpannableStringBuilder(spannable);
ssb.removeSpan(this.spanBackgroundColored);
ssb.setSpan(this.spanBackgroundColored, this.mStartSelect,
this.mEndSelect, Spannable.SPAN_USER);
this.textView.setText(ssb);
this.textView.requestLayout();
if (this.selectableTextViewerListener != null) {
this.selectableTextViewerListener.updateSelection(this);
}
}
return retLayout;
}
protected void showSelectionControls() {
if (this.mStartSelect > -1 && this.mEndSelect > -1) {
Layout layout = updateSelectionSpan();
Rect parentTextViewRect = new Rect();
LayoutParams startLP = (LayoutParams) this.imgStartSelect
.getLayoutParams();
float xStart = layout.getPrimaryHorizontal(this.mStartSelect)
- mImgWidth / 2;
float yStart = layout.getLineBounds(
layout.getLineForOffset(this.mStartSelect),
parentTextViewRect);
startLP.setMargins((int) xStart, (int) yStart, -1, -1);
this.imgStartSelect.setLayoutParams(startLP);
this.imgStartSelect.setVisibility(View.VISIBLE);
LayoutParams endLP = (LayoutParams) this.imgEndSelect
.getLayoutParams();
float xEnd = layout.getPrimaryHorizontal(this.mEndSelect)
- mImgWidth / 2;
float yEnd = layout.getLineBounds(
layout.getLineForOffset(this.mEndSelect),
parentTextViewRect);
endLP.setMargins((int) xEnd, (int) yEnd, -1, -1);
this.imgEndSelect.setLayoutParams(endLP);
this.imgEndSelect.setVisibility(View.VISIBLE);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (this.imgStartSelect != null) {
if (this.imgStartSelect.getVisibility() == View.GONE) {
this.onTouchDownCalcSelections(event);
disallowIntercept(false);
} else {
this.stopSelecting();
}
}
} else {
this.disallowIntercept(false);
}
return super.onTouchEvent(event);
}
private void hideSelectionControls() {
this.imgStartSelect.setVisibility(View.GONE);
this.imgEndSelect.setVisibility(View.GONE);
}
private int getOffsetByCoordinates(int x, int y) {
int retOffset = -1;
Layout layout = this.textView.getLayout();
if (layout != null) {
int line = layout.getLineForVertical(y);
retOffset = layout.getOffsetForHorizontal(line, x);
}
return retOffset;
}
private void onTouchDownCalcSelections(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
this.mStartSelect = getOffsetByCoordinates(x, y);
if (this.mStartSelect > -1) {
// Calculate text end
String tempStr = this.textView.getText().toString();
tempStr = tempStr.substring(this.mStartSelect);
Pattern pt = Pattern.compile("\\s");
Matcher mt = pt.matcher(tempStr);
if (mt.find()) {
String match = mt.group(0);
tempStr = tempStr.substring(0, tempStr.indexOf(match));
}
this.mEndSelect = this.mStartSelect + tempStr.length();
}
}
public void setText(SpannableStringBuilder builder) {
this.textView.setText(builder);
}
public ImageView getImgEndSelect() {
return imgEndSelect;
}
public ImageView getImgStartSelect() {
return imgStartSelect;
}
/**
* For this all doing
*
* #return
*/
public String getSelectedText() {
String retSelectedString = null;
if (this.mStartSelect > -1 && this.mEndSelect > -1) {
retSelectedString = this.textView.getText()
.subSequence(this.mStartSelect, this.mEndSelect).toString();
}
return retSelectedString;
}
/**
* Hides cursors and clears
*
* #return
*/
public void stopSelecting() {
this.hideSelectionControls();
SpannedString spannable = (SpannedString) this.textView.getText();
SpannableStringBuilder ssb = new SpannableStringBuilder(spannable);
ssb.removeSpan(this.spanBackgroundColored);
this.setText(ssb);
if (selectableTextViewerListener != null) {
selectableTextViewerListener.stopSelectingText(
SelectableTextViewer.this, getSelectedText());
}
}
}
you have to this method as re-use, customize this method as per your use. this is just a concept.
// text comes from textview.gettext or database text and invalidate the view.
protected Layout updateSelectionSpan(Strint text) {
Layout retLayout = this.textView.getLayout();
if (this.mStartSelect > -1 && this.mEndSelect > -1) {
if (this.mStartSelect > this.mEndSelect) {
int temp = mEndSelect;
this.mEndSelect = mStartSelect;
this.mStartSelect = temp;
showSelectionControls();
}
SpannedString spannable = (SpannedString) text;
SpannableStringBuilder ssb = new SpannableStringBuilder(spannable);
ssb.removeSpan(this.spanBackgroundColored);
ssb.setSpan(this.spanBackgroundColored, this.mStartSelect,
this.mEndSelect, Spannable.SPAN_USER);
this.textView.setText(ssb);
this.textView.requestLayout();
if (this.selectableTextViewerListener != null) {
this.selectableTextViewerListener.updateSelection(this);
}
}
return retLayout;
}
I'm really new on Android Programming, i have any error on my code,anyone can help if something wrong in this code? The log cat show me these errors:
08-07 11:59:46.773: E/AndroidRuntime(26185): java.lang.RuntimeException: Unable to start activity
ComponentInfo{uiv.makedirect.activity/uiv.makedirect.activity.ManagerActivity}: java.lang.NullPointerException
08-07 11:59:46.773: E/AndroidRuntime(26185): at uiv.makedirect.utilities.RadioStateDrawable.<init>(RadioStateDrawable.java:78)
08-07 11:59:46.773: E/AndroidRuntime(26185): at uiv.makedirect.utilities.TabBarButton.setState(TabBarButton.java:66)
And my code :
Activity i using for create Tabactivity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
* set this activity as the tab bar delegate so that onTabChanged is called when users tap on the bar
*/
setDelegate(new SliderBarActivityDelegateImpl());
Intent home = new Intent(this, HomeActivity.class);
Intent feed = new Intent(this, FeedActivity.class);
Intent cart = new Intent(this, CartActivity.class);
Intent invite = new Intent(this, InviteActivity.class);
Intent account = new Intent(this, AccountActivity.class);
/*
* This adds a title and an image to the tab bar button Image should be a PNG file with transparent background. Shades are opaque areas in on and off state are specific as parameters
*/
this.addTab("Home", R.drawable.star, RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_BLUE, home);
this.addTab("Feed", R.drawable.icon_feed, RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_BLUE, feed);
this.addTab("Cart", R.drawable.ico_cart, RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_BLUE, cart);
this.addTab("Invite", R.drawable.ico_invite, RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_BLUE, invite);
this.addTab("Account", R.drawable.star, RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_BLUE, account);
/*
* commit is required to redraw the bar after add tabs are added if you know of a better way, drop me your suggestion please.
*/
commit();
}
ScrollableTabActivity:
public class ScrollableTabActivity extends ActivityGroup implements RadioGroup.OnCheckedChangeListener{
private LocalActivityManager activityManager;
private LinearLayout contentViewLayout;
private LinearLayout.LayoutParams contentViewLayoutParams;
private HorizontalScrollView bottomBar;
private RadioGroup.LayoutParams buttonLayoutParams;
private RadioGroup bottomRadioGroup;
private Context context;
private List intentList;
private List titleList;
private List states;
private SliderBarActivityDelegate delegate;
private int defaultOffShade;
private int defaultOnShade;
private IntentFilter changeTabIntentFilter;
private ChangeTabBroadcastReceiver changeTabBroadcastReceiver;
public static String CURRENT_TAB_INDEX;
public static String ACTION_CHANGE_TAB = "com.mobyfactory.changeTab";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
activityManager = getLocalActivityManager();
setContentView(R.layout.customslidingtabhost);
contentViewLayout = (LinearLayout)findViewById(R.id.contentViewLayout);
bottomBar = (HorizontalScrollView)findViewById(R.id.bottomBar);
bottomRadioGroup = (RadioGroup)findViewById(R.id.bottomMenu);
contentViewLayoutParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
defaultOffShade = RadioStateDrawable.SHADE_GRAY;
defaultOnShade = RadioStateDrawable.SHADE_YELLOW;
bottomRadioGroup.setOnCheckedChangeListener(this);
intentList = new ArrayList();
titleList = new ArrayList();
states = new ArrayList();
buttonLayoutParams = new RadioGroup.LayoutParams(320/5, RadioGroup.LayoutParams.WRAP_CONTENT);
}
public void onResume()
{
changeTabIntentFilter = new IntentFilter(ACTION_CHANGE_TAB);
changeTabBroadcastReceiver = new ChangeTabBroadcastReceiver();
registerReceiver(changeTabBroadcastReceiver, changeTabIntentFilter);
super.onResume();
}
public void onPause()
{
unregisterReceiver(changeTabBroadcastReceiver);
super.onPause();
}
public void commit()
{
bottomRadioGroup.removeAllViews();
int optimum_visible_items_in_portrait_mode = 5;
try
{
WindowManager window = getWindowManager();
Display display = window.getDefaultDisplay();
int window_width = display.getWidth();
optimum_visible_items_in_portrait_mode = (int) (window_width/64.0);
}
catch (Exception e)
{
optimum_visible_items_in_portrait_mode = 5;
}
int screen_width = getWindowManager().getDefaultDisplay().getWidth();
int width;
if (intentList.size()<=optimum_visible_items_in_portrait_mode)
{
width = screen_width/intentList.size();
}
else
{
width = screen_width/5;
//width = 320/5;
}
RadioStateDrawable.width = width;
RadioStateDrawable.screen_width = screen_width;
buttonLayoutParams = new RadioGroup.LayoutParams(width, RadioGroup.LayoutParams.WRAP_CONTENT);
for (int i=0; i<intentList.size(); i++)
{
TabBarButton tabButton = new TabBarButton(this);
int[] iconStates = (int[]) states.get(i);
if (iconStates.length==1)
tabButton.setState( titleList.get(i).toString(),iconStates[0]);
else if (iconStates.length==2)
tabButton.setState(titleList.get(i).toString(), iconStates[0], iconStates[1]);
else if (iconStates.length==3)
tabButton.setState(titleList.get(i).toString(), iconStates[0], iconStates[1], iconStates[2]);
tabButton.setId(i);
tabButton.setGravity(Gravity.CENTER);
bottomRadioGroup.addView(tabButton, i, buttonLayoutParams);
}
setCurrentTab(0);
}
protected void addTab(String title, int offIconStateId, int onIconStateId, Intent intent)
{
int[] iconStates = {onIconStateId, offIconStateId};
states.add(iconStates);
intentList.add(intent);
titleList.add(title);
//commit();
}
protected void addTab(String title, int iconStateId, Intent intent)
{
//int[] iconStates = {iconStateId};
int[] iconStates = {iconStateId, defaultOffShade, defaultOnShade};
states.add(iconStates);
intentList.add(intent);
titleList.add(title);
//commit();
}
protected void addTab(String title, int iconStateId, int offShade, int onShade, Intent intent)
{
int[] iconStates = {iconStateId, offShade, onShade};
states.add(iconStates);
intentList.add(intent);
titleList.add(title);
//commit();
}
And RadioStateDrawable for display image in tab:
public class RadioStateDrawable extends Drawable {
private Bitmap bitmap;
private Bitmap highlightBitmap;
private Shader shader;
private Shader textShader;
Context context;
public static int width;
public static int screen_width;
private boolean highlight;
private String label;
public static final int SHADE_GRAY = 0;
public static final int SHADE_BLUE = 1;
public static final int SHADE_MAGENTA = 2;
public static final int SHADE_YELLOW = 3;
public static final int SHADE_GREEN = 4;
public static final int SHADE_RED = 5;
public static final int SHADE_ORANGE = 6;
public RadioStateDrawable(Context context, int imageID, String label, boolean highlight, int shade)
{
super();
this.highlight = highlight;
this.context = context;
this.label = label;
InputStream is = context.getResources().openRawResource(imageID);
bitmap = BitmapFactory.decodeStream(is).extractAlpha();
setShade(shade);
highlightBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.bottom_bar_highlight);
}
public RadioStateDrawable(Context context, int imageID, String label, boolean highlight, int startGradientColor, int endGradientColor)
{
super();
this.highlight = highlight;
this.context = context;
this.label = label;
InputStream is = context.getResources().openRawResource(imageID);
bitmap = BitmapFactory.decodeStream(is).extractAlpha();
int[] shades = new int[] { startGradientColor, endGradientColor };
shader = new LinearGradient(0, 0, 0, bitmap.getHeight(), shades, null, Shader.TileMode.MIRROR);
}
public void setShade(int shade)
{
int[] shades = new int[2];
switch (shade)
{
case SHADE_GRAY: {
shades = new int[] { Color.LTGRAY, Color.DKGRAY };
break;
}
case SHADE_BLUE: {
shades = new int[] { Color.CYAN, Color.BLUE };
break;
}
case SHADE_RED: {
shades = new int[] { Color.MAGENTA, Color.RED };
break;
}
case SHADE_MAGENTA: {
shades = new int[] { Color.MAGENTA, Color.rgb(292, 52, 100) };
break;
}
case SHADE_YELLOW: {
shades = new int[] { Color.YELLOW, Color.rgb(255, 126, 0) };
break;
}
case SHADE_ORANGE: {
shades = new int[] { Color.rgb(255, 126, 0), Color.rgb(255, 90, 0) };
break;
}
case SHADE_GREEN: {
shades = new int[] { Color.GREEN, Color.rgb(0, 79, 4) };
break;
}
}
shader = new LinearGradient(0, 0, 0, bitmap.getHeight(), shades, null, Shader.TileMode.MIRROR);
if (highlight)
textShader = new LinearGradient(0, 0, 0, 10, new int[] { Color.WHITE, Color.LTGRAY }, null, Shader.TileMode.MIRROR);
else
textShader = new LinearGradient(0, 0, 0, 10, new int[] { Color.LTGRAY, Color.DKGRAY }, null, Shader.TileMode.MIRROR);
}
#Override
public void draw(Canvas canvas) {
int bwidth = bitmap.getWidth();
int bheight = bitmap.getHeight();
/*
* if (width==0) { if (screen_width==0) screen_width = 320; width=screen_width/5; }
*/
int x = (width - bwidth) / 2;
int y = 2;
canvas.drawColor(Color.TRANSPARENT);
Paint p = new Paint();
p.setColor(Color.WHITE);
p.setStyle(Paint.Style.FILL);
p.setTextSize(19);
p.setTypeface(Typeface.DEFAULT_BOLD);
p.setFakeBoldText(true);
p.setTextAlign(Align.CENTER);
p.setShader(textShader);
p.setAntiAlias(true);
canvas.drawText(label, width / 2, y + bheight + 20, p);
p.setShader(shader);
canvas.drawBitmap(bitmap, x, y, p);
}
ERROR APPEARS WHEN I CHANGE THE IMAGE TAB
my guess is that your app crashes because of this last line in your RadioStateDrawable function.
the way to get a specific drawable from your resources is like this:
int id = getResources().getIdentifier(bottom_bar_highlight,"drawable", getPackageName());
BitmapFactory.decodeResource(getResources(), id);
After reading your code clearly, I think error java.lang.NullPointerException may come from context.getResources(). I googled about usage of context.getResources().openRawResource() and context.getResources().getIdentifier().
I think that you passed wrong parameter to this method: context.getResources().getIdentifier() .
You may try this:
int id = context.getResources().getIdentifier("drawable/bottom_bar_highlight","drawable", context.getPackageName());
Good luck.
It looks like this both in the emulator and on the phone. It's always a random square that is broken.
And here is the code from the SurfaceView class, the most relevant part is in prepareBackground() :
Code begins:
public class MenuBackgroundView extends SurfaceView implements SurfaceHolder.Callback
{
private Paint mPaint;
private Bitmap blocks12x12;
private boolean draw = false;
private Context ctx;
//private int begOffX;
private int offX;
private int offY;
private int mWidth = 1;
private int mHeight = 1;
private ViewThread mThread;
private int calcSizeXY;
public MenuBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
mThread = new ViewThread(this);
mPaint = new Paint();
mPaint.setColor(Color.RED);
ctx = context;
}
public void doDraw(long elapsed, Canvas canvas) {
canvas.drawColor(Color.BLUE);
if(draw)
{
canvas.drawBitmap(blocks12x12, offX, offY, mPaint);
}
canvas.drawText("FPS: " + Math.round(1000f / elapsed) + " Elements: ", 10, 10, mPaint);
}
public void animate(long elapsed)
{
/*
//elapsed = elapsed/10;
offX = (offX+2);
if(offX >= 0)
{
offX -= 2*calcSizeXY;
}
offY = (offY+3);
if(offY >= 0)
{
offY -= 2*calcSizeXY;
}
//offY = (offY + (int)(elapsed/10f)) % calcSizeXY*2;//
*
*///
}
public void prepareBackground()
{
if(mWidth <= 1 || mHeight <= 1 )
return;
Log.d("Menu", "prepareBackground");
if(mHeight > mWidth)
{
calcSizeXY = mHeight/10;
}
else
{
calcSizeXY = mWidth/10;
}
offX = -2*calcSizeXY;
Bitmap block = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.block);
block = Bitmap.createScaledBitmap(block, calcSizeXY, calcSizeXY, false);
// Group together
int sizeX = 12*calcSizeXY;
int sizeY = 12*calcSizeXY;
blocks12x12 = Bitmap.createBitmap(sizeX, sizeY, Bitmap.Config.ARGB_8888);
Canvas blocks12x12Canvas = new Canvas(blocks12x12);
for(int i = 0; i < 14; i+=2)
{
for(int j = 0; j < 14; j+=2)
{
blocks12x12Canvas.drawBitmap(block, (j*calcSizeXY), (i*calcSizeXY), mPaint);
}
}
// "Memory leak"
block.recycle();
draw = true;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mWidth = width;
mHeight = height;
prepareBackground();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
prepareBackground();
if (!mThread.isAlive()) {
mThread = new ViewThread(this);
mThread.setRunning(true);
mThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread.isAlive()) {
mThread.setRunning(false);
freeMem();
}
}
public void freeMem() {
// TODO Auto-generated method stub
draw = false;
blocks12x12.recycle(); // "Memory leak"
}
}
Ok I figured it out, simply make the thread sleep for 1ms:
blocks12x12 = Bitmap.createBitmap(sizeX, sizeY, Bitmap.Config.ARGB_8888);
Canvas blocks12x12Canvas = new Canvas(blocks12x12);
for(int i = 0; i < 14; i+=2)
{
for(int j = 0; j < 14; j+=2)
{
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
blocks12x12Canvas.drawBitmap(block, (j*calcSizeXY), (i*calcSizeXY), mPaint);
}
}