Custom View not showing: no height, but still width - java

In my current project I run into an dead end. My custom view, only created to show a specific color, won't show in the view of my emulator (although it seems to show up correctly in the editor of Eclipse) except if it had a minimum height, but then it only get this exact height. I want it to match_parent.
The problem might be that it is in the item layout of a list view.
That's the code of my Custom View:
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class ColorView extends View {
private int mColor;
private Context mContext;
private int width;
private int height;
public ColorView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ColorView, 0, 0);
try {
mColor = a.getColor(R.styleable.ColorView_color, 0xFFFFFF);
} finally {
a.recycle();
}
}
public void setColor(int hexColor) {
mColor = hexColor;
invalidate();
}
public void setColorFromResource(int resID) {
mColor = mContext.getResources().getColor(resID);
invalidate();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.d("DEBUG", Integer.toString(w) + " " + Integer.toString(h));
width = w;
height = h;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(mColor);
Log.d("DEBUG", "drawn");
}
}
And a simplified version of my layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:raabeapp="http://schemas.android.com/apk/res/com.example.myapp"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/row_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.example.myapp.ColorView
android:id="#+id/status_view"
android:layout_width="20dip"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dip"
android:minHeight="50dp"
raabeapp:color="#FF0000" />
<TextView
android:id="#+id/hour_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/status_view"
android:text="1"
android:textSize="#dimen/hour_textsize"
android:width="70dp" />
<TextView
android:id="#+id/text_hourtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/hour_view"
android:text="#string/hour_text"
android:textSize="#dimen/hourtext_textsize" />

Ok, I figured out a workaround:
When I use a LinearLayout instead of a RelativeLayout I get the result I want.
It seems that the problem lies in the RelativeLayout. If someone knows why this is, or how I could still use a RelativeLayout I would be very interested. This answer does not provide a full solution, but in case someone runs into my problem it could provide a ugly workaround.

Use android:layout_height="match_parent" for your RelativeLayout.

Related

Color detection in android (java) delivers wrong RGB values

I am trying to make a program in Android Studio using java, where I can determine the RGB values at the point where the user clicked on the image. The code is working so far, but it gives wrong RGB values as output. They also seem to vary, based on the location where I click, even if the color that should be put out is the same. My guess is, that there is something up with the Bitmap, that I don't know about.
My MainActivity :
package com.example.fitme;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int evX = (int) ev.getX();
final int evY = (int) ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN :
break;
case MotionEvent.ACTION_UP :
ImageView img = (ImageView) findViewById (R.id.body_front_map);
img.setDrawingCacheEnabled(true);
Bitmap imgbmp = Bitmap.createBitmap(img.getDrawingCache());
img.setDrawingCacheEnabled(false);
int pxl = imgbmp.getPixel(evX, evY);
int redComponent = Color.red(pxl);
int greenComponent = Color.green(pxl);
int blueComponent = Color.blue(pxl);
Toast.makeText(MainActivity.this,"RED: "+redComponent+" GREEN: "+greenComponent+" BLUE: "+blueComponent, Toast.LENGTH_SHORT).show();
break;
}
return false;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="#+id/body_front_map"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:background="#drawable/body_front_map"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The Image I am trying to use

Android clip custom view to path

I am trying to clip one custom view (linearlayout) to another (simple view). I want to clip the path of the linear layout to the path of the view which is a circle. Here are my custom views:
Circle
package classes;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
public class Circle extends View {
private Paint paint = new Paint();
private Path path = new Path();
public Circle(Context context) {
super(context);
}
public Circle(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public Circle(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setColor(int color) {
paint.setColor(color);
invalidate();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
path = new Path();
path.addCircle(getWidth() / 2 - getWidth() / 5, getHeight() / 2 - getHeight() / 5, (getWidth() + getHeight()) / 4, Path.Direction.CW);
path.close();
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint);
}
public Path getPath() {
return path;
}
}
Linear Layout:
package classes;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class ClippedLinearLayout extends LinearLayout {
public ClippedLinearLayout(Context context) {
super(context);
this.setWillNotCacheDrawing(false);
invalidate();
}
public ClippedLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setWillNotCacheDrawing(false);
invalidate();
}
public ClippedLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWillNotCacheDrawing(false);
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.clipPath(Blog.circle2.getPath());
}
}
What am i doing wrong?
EDIT:
My xml:
<RelativeLayout
android:id="#+id/menuButtonContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true">
<classes.Circle
android:id="#+id/circle2"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone" />
<classes.Circle
android:id="#+id/menuCircle"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:visibility="gone" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="22dp"
android:background="#drawable/menu_button" />
</RelativeLayout>
<Button
android:id="#+id/button3"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:background="#drawable/close" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:background="#FF0000"
android:contentDescription="#string/ContentDescription"
android:gravity="center"
android:padding="10dp"
android:text="#string/failLogin"
android:textColor="#FFFFFF" />
<ScrollView
android:id="#+id/menuScrollView6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:clickable="false">
<classes.ClippedLinearLayout
android:id="#+id/linearLayout5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:visibility="gone"
android:orientation="vertical" />
</ScrollView>

Custom View InflateException For Drawing Application in Fragment

I am trying to code a touchscreen interactive drawing application inside android studios with a fragment; however, I am receiving an error of but fails to find what it is caused by and how to fix it. I am a beginner to app development and simply was following a tutorial. See the link below and please notify me if you need additional information. Thank you so much in advance!
I suspect it is caused by the package name in the xml file or the constructors in the java file!
Problems/Errors
at
com.app2016.alexker.matchplanning.MatchPlanning.onCreateView(MatchPlanning.java:67)
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app2016.alexker.matchplanning/com.app2016.alexker.matchplanning.MainActivity}:
android.view.InflateException: Binary XML file line #19: Error
inflating class com.codepath.example.simpledrawapp.SimpleDrawingView
Java Class
package com.app2016.alexker.matchplanning;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;
import android.util.AttributeSet;
/**
* Created by AlexKer on 16-02-06.
*/
public class SimpleDrawingView extends View {
//set up initial paint color
private final int paintColor = Color.BLACK;
//defines paint and canvas
private Paint drawPaint;
//path
private Path path = new Path();
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, drawPaint);
}
public SimpleDrawingView(Context context){
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
setupPaint();
}
public SimpleDrawingView(Context context, AttributeSet attrs){
super(context, attrs);
/*setFocusable(true);
setFocusableInTouchMode(true);
setupPaint();*/
}
private void setupPaint() {
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(5);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
}
// Get x and y and append them to the path
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Starts a new line in the path
path.moveTo(pointX, pointY);
break;
case MotionEvent.ACTION_MOVE:
// Draws line between last point and this point
path.lineTo(pointX, pointY);
break;
default:
return false;
}
postInvalidate(); // Indicate view should be redrawn
return true; // Indicate we've consumed the touch
}
}
Below is the onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_match_planning, container, false);
return view;
}
And XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_match_plan"
android:orientation="vertical"
android:gravity="center|top"
tools:context="com.app2016.alexker.matchplanning.MatchPlanning"
android:background="#drawable/field">
<!-- TODO: Update blank fragment layout -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.codepath.example.simpledrawapp.SimpleDrawingView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/SimpleDrawingView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Actually, the package name is also wrong in XML. Should be
com.app2016.alexker.matchplanning.
I have no idea what the view is you're trying to use, but this seems super unusual:
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
Try this:
<com.app2016.alexker.matchplanning.SimpleDrawingView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/SimpleDrawingView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Also -- currently, the LinearLayout or RelativeLayout is useless.

Android custom compound component's contents won't appear

I'm trying to create a custom view, a calendar. The views inside this component are inflated from a xml layout. I have studied several tutorials and three or four similar (or even identical) questions on stack overflow but nothing seems to work. I'd appreciate it if you could point out the problem. Thanks in advance and here are the codes.
kcalendar_view.xml // the layout for the custom view
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<Button
android:id="#+id/btnKCalendarNavLeft"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#drawable/kcalendar_nav_button_bg"
android:text="<" />
<TextView
android:id="#+id/txvKCalendarNavTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/btnKCalendarNavRight"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#drawable/kcalendar_nav_button_bg"
android:text=">" />
</LinearLayout>
<GridView
android:id="#+id/gridViewKCalendar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="7" >
</GridView>
</merge>
KCalendarView.java // the custom view's class
package ir.kcoder.KCalendarView;
import ir.kcoder.persiancalendarweather.R;
import java.util.Calendar;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import com.samanpr.jalalicalendar.JalaliCalendar;
import com.samanpr.jalalicalendar.JalaliCalendar.YearMonthDate;
public class KCalendarView extends LinearLayout {
private YearMonthDate currentJalaliDate;
private int parentWidth, parentHeight;
private Button leftButton, rightButton;
private GridView gridView;
private KCalendarAdapter calendarAdapter;
private Context context;
private View inflated;
public KCalendarView(Context context) {
super(context);
}
public KCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setOrientation(LinearLayout.VERTICAL);
setGravity(Gravity.CENTER);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflated = inflater.inflate(R.layout.kcalendar_view, this, true);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
init(getContext());
}
private void init(Context context) {
Calendar c = Calendar.getInstance();
YearMonthDate currentGregDate = new YearMonthDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
currentJalaliDate = JalaliCalendar.gregorianToJalali(currentGregDate);
leftButton = (Button)findViewById(R.id.btnKCalendarNavLeft);
rightButton = (Button)findViewById(R.id.btnKCalendarNavRight);
gridView = (GridView)findViewById(R.id.gridViewKCalendar);
if(gridView != null) {
calendarAdapter = new KCalendarAdapter(context, currentJalaliDate.getYear(),
currentJalaliDate.getMonth());
gridView.setAdapter(calendarAdapter);
}
}
public void nextMonth() {
}
public void prevMonth() {
}
// #Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// parentWidth = MeasureSpec.getSize(widthMeasureSpec);
// parentHeight = MeasureSpec.getSize(heightMeasureSpec);
// this.setMeasuredDimension(parentWidth, parentHeight);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// }
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
}
}
activity_main.xml // I use this tag to include the custom view in my app
<ir.kcoder.KCalendarView.KCalendarView
android:id="#+id/kCalendarView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" >
</ir.kcoder.KCalendarView.KCalendarView>
Updated
Try this I think it should work
public class KCalendarView extends LinearLayout {
private YearMonthDate currentJalaliDate;
private int parentWidth, parentHeight;
private Button leftButton, rightButton;
private GridView gridView;
private KCalendarAdapter calendarAdapter;
public KCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
doInflate();
}
private void doInflate() {
setOrientation(LinearLayout.VERTICAL);
setGravity(Gravity.CENTER);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
inflate(getContext(), R.layout.kcalendar_view, this);
leftButton = (Button)findViewById(R.id.btnKCalendarNavLeft);
rightButton = (Button)findViewById(R.id.btnKCalendarNavRight);
gridView = (GridView)findViewById(R.id.gridViewKCalendar);
init();
}
private void init() {
Calendar c = Calendar.getInstance();
YearMonthDate currentGregDate = new YearMonthDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
currentJalaliDate = JalaliCalendar.gregorianToJalali(currentGregDate);
calendarAdapter = new KCalendarAdapter(context, currentJalaliDate.getYear(), currentJalaliDate.getMonth());
gridView.setAdapter(calendarAdapter);
}
public void nextMonth() {
}
public void prevMonth() {
}
}

Android, painting on my own, "divided" layout doesn't work

I need to create a layout, which must be divided in half, like this:
-------
| |
| A |
| |
-------
| |
| B |
| |
-------
Where:
A - this is the place, where I can draw points with a finger;
B - it is an example ListView.
It looks like no object from class SampleView was created, so painting in A doesn't work.
What's wrong with that?
How do I need to fix painting?
drawing_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical" >
<View
class="com.example.proj.SampleView"
android:id="#+id/sampleView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".50" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".50" >
</ListView>
</LinearLayout>
SampleView.java:
package com.example.proj;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class SampleView extends View implements OnTouchListener {
private static final String TAG = "SampleView";
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
public SampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
Log.i(TAG, "Created SampleView!");
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 5, paint);
Log.d(TAG, "Painting: "+point);
}
}
public boolean onTouch(View view, MotionEvent event) {
if(event.getAction() != MotionEvent.ACTION_DOWN)
return super.onTouchEvent(event);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
Log.d(TAG, "point: " + point);
return true;
}
}
class Point {
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
MainActivity.java:
package com.example.proj;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.widget.ListView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawing_activity);
final ListView listview = (ListView) findViewById(R.id.listView1);
String[] values = new String[] { "Element1", "Element2" };
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < values.length; ++i) {
list.add(values[i]);
}
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
listview.setAdapter(adapter);
}
}
In your xml must be:
<com.example.proj.SampleView
android:id="#+id/sampleView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".50" />
OR: view with non-capitalized "V"
<view
class="com.example.proj.SampleView"
android:id="#+id/sampleView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".50" />
Both tags view and View exist, however View will generate a new View class whereas view will generate from the class tag.

Categories