I have RecycleViewer with Canvas view in list item. How can I change backgrouncolor of Canvas view in my RecycleViewerAdapter ?
Below is my onBindViewHolder method in my RecycleViewerAdapter
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.openprice.setText(mopenPrice.get(position));
//How can I change backgrouncolor canvas view ????
}
my ViewHolder
public ViewHolder(View itemView) {
super(itemView);
openprice = (TextView) itemView.findViewById(R.id.openprice);
viewx = (View) itemView.findViewById(R.id.viewx);
}
itemlist.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#drawable/border_listfavorite"
>
<view class="com.eusecom.exforu.MyView"
android:layout_width="fill_parent"
android:layout_height="20dp"
android:layout_alignParentLeft="true"
android:id="#+id/viewx"/>
<TextView
android:id="#+id/opentxt"
android:text="#string/opentxt"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/viewx"
/>
<TextView
android:id="#+id/openprice"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/opentxt"
android:layout_below="#+id/viewx"
/>
</RelativeLayout>
MyView.java
public class MyView extends View {
public MyView(Context cxt, AttributeSet attrs) {
super(cxt, attrs);
setMinimumHeight(100);
setMinimumWidth(100);
}
#Override
protected void onDraw(Canvas cv) {
cv.drawColor(Color.WHITE);
Paint p = new Paint();
p.setColor(Color.GREEN);
p.setStrokeWidth(5);
cv.drawLine(20, 0, 20, cv.getHeight(), p);
}
}
Use invalidate() method for calling onDraw method.
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.viewx.setText(mopenPrice.get(position));
if(condition){
holder.viewx.setCustomColor(Color.GREEN);
holder.viewx.invalidate();
}
}
public class MyView extends View {
private int color = Color.WHITE;
public MyView(Context cxt, AttributeSet attrs) {
super(cxt, attrs);
setMinimumHeight(100);
setMinimumWidth(100);
}
#Override
protected void onDraw(Canvas cv) {
cv.drawColor(color);
Paint p = new Paint();
p.setColor(Color.GREEN);
p.setStrokeWidth(5);
cv.drawLine(20, 0, 20, cv.getHeight(), p);
}
public void setCustomColor(int color){
this.color = color;
}
public ViewHolder(View itemView) {
private MyView viewx;
super(itemView);
openprice = (TextView) itemView.findViewById(R.id.openprice);
viewx = (MyView) itemView.findViewById(R.id.viewx);
}
Related
What I am trying to achieve:
measure a container View in my layout, mainContainer, that is defined in the XML
pass the mainContainer's width and height to a different custom View before onDraw() is called
I want to pass the width and height so the custom View knows where to draw canvas.drawBitmap using coordinates
The custom view will be programmatically created from code
How can I pass the measured int width and int height to my custom View before onDraw() is called?
Custom View
public class AvatarView extends ImageView {
private Bitmap body;
private Bitmap hat;
public AvatarView(Context context) {
super(context);
init();
}
public AvatarView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AvatarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
body = BitmapFactory.decodeResource(getResources(), R.drawable.battle_run_char);
hat = BitmapFactory.decodeResource(getResources(), R.drawable.red_cartoon_hat);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(body, x, y, null);
canvas.drawBitmap(hat, x, y, null);
}
}
Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_customize_avatar, container, false);
final RelativeLayout mainContainer = (RelativeLayout) view.findViewById(R.id.main_container);
TwoWayView inventoryList = (TwoWayView) view.findViewById(R.id.inventory);
inventoryList.setAdapter(null);
inventoryList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
}
});
mainContainer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
// Retrieve the width and height
containerWidth = mainContainer.getWidth();
containerHeight = mainContainer.getHeight();
// Remove global listener
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
mainContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
mainContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
return view;
}
XML
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:clickable="true"
android:background="#fff" >
<com.walintukai.lfdate.CustomTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textStyle="bold"
android:textColor="#fff"
android:textSize="20sp"
android:textAllCaps="true"
android:text="#string/customize_avatar"
android:background="#009BFF" />
<RelativeLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<org.lucasr.twowayview.TwoWayView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/inventory"
style="#style/HorizontalListView"
android:layout_width="match_parent"
android:layout_height="80dp"
android:drawSelectorOnTop="false"
android:background="#f3f3f3" />
</LinearLayout>
What you need to do is add a flag inside your AvatarView that checks if are you going to render this or not in your onDraw method.
sample:
public class AvatarView extends ImageView {
private Bitmap body;
private Bitmap hat;
private int containerHeight;
private int containerWidth;
private boolean isRender = false;
public AvatarView(Context context) {
super(context);
init();
}
public AvatarView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AvatarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public void setMeasure(int containerWidth, int containerHeight )
{
this.containerHeight = containerHeight;
this.containerWidth = containerWidth;
}
private void init() {
body = BitmapFactory.decodeResource(getResources(), R.drawable.battle_run_char);
hat = BitmapFactory.decodeResource(getResources(), R.drawable.red_cartoon_hat);
}
public void setRender(boolean render)
{
isRender = render;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(isRender )
{
canvas.drawBitmap(body, x, y, null);
canvas.drawBitmap(hat, x, y, null);
}
}
}
Now it wont render when you dont call setRender and set it to true. And just call setMeasure to pass the value.
First you need to call setMeasure and after you set the measure you then call setRender(true) and call invalidate() to call the onDraw method to render the images
I have a custom view (a class extending View) that I'd like to add as a header of List View. Here's the code snippet:
public class MyActivity extends RoboListActivity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View header = getLayoutInflater().inflate(R.layout.myactivity_apps_header, null);
getListView().addHeaderView(header);
...more code
}
But, I can't see anything. But, when I tried to add a non-custom view, it works. Am I missing something, please guide
Providing Complete Source Code
Custom View
public class SpaceCustomView extends View {
private Paint mPaint;
private Paint mTextPaint;
private final String mMessage = "Foo Bar";
private Rect mBounds;
public StorageSpaceCustomView(Context context) {
super(context);
initInput();
}
public StorageSpaceCustomView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
initInput();
}
public StorageSpaceCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initInput();
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
#Override
public void onDraw(android.graphics.Canvas canvas) {
canvas.drawRect(30, 30, 800, 80, mPaint);
canvas.drawText(mMessage, 30, 60, mTextPaint);
}
private void initInput() {
mBounds = new Rect();
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextAlign(Paint.Align.LEFT);
mTextPaint.setTextSize(20);
mTextPaint.getTextBounds(mMessage, 0, mMessage.length(), mBounds);
}
}
Header Layout XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.mycompany.app.view.custom.SpaceCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Activity Class
public class AppsActivity extends RoboListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//add header and footer views
View header = getLayoutInflater().inflate(R.layout.activity_apps_header, null);
getListView().addHeaderView(header);
View footer = getLayoutInflater().inflate(R.layout.activity_pps_footer, null);
getListView().addFooterView(footer);
List<AppInfo> applicationList = Mycatalog.getPromotions();
AppListAdapter adapter = new AppListAdapter(this, applicationList);
setListAdapter(adapter);
}
private class AppListAdapter extends ArrayAdapter<AppInfo> {
public AppListAdapter(Activity activity, List<AppInfo> apps) {
super(activity, android.R.layout.simple_list_item_1, apps);
}
#Override
public boolean isEmpty(){
return false;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// if we weren't given a view, inflate one
if (null == convertView) {
convertView = getLayoutInflater()
.inflate(R.layout.activity_uninstall_apps, null);
}
return convertView;
}
}
}
Conclusion: I can see the footer but not the header.
ListView shows headers and footers only when it's Adapter's isEmpty() returns false.
So try setting an adapter that does that...
I am having a custom layout for the list fragment. Inside that custom list layout, i want to put another custom view (which do drawing things). So my question is: how to add another view to convertView in method getView().
Here is my getView method:
private class TrainingAdapter extends ArrayAdapter<Product>
{
public TrainingAdapter(ArrayList<Product> list) {
super(getActivity(), 0, list);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = getActivity().getLayoutInflater().inflate(R.layout.trainings_custom_layer_listfragment, null);
}
Product p = getItem(position);
//references to text view and image view goes here
//begin to work with custom view
StarView sv = (StarView) convertView.findViewById(R.id.star_view);
return convertView; }
Here is my layout:
<ImageView android:id="#+id/imageview_product_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="mini photo" />
<TextView android:id="#+id/textview_training_title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toRightOf="#id/imageview_product_category"
android:textColor="#color/text_color_white" />
<TextView android:id="#+id/textview_training_location"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toRightOf="#id/imageview_product_category"
android:layout_below="#id/textview_training_title"
android:textColor="#color/text_color_white" />
<TextView android:id="#+id/textview_training_datetime"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toRightOf="#id/imageview_product_category"
android:layout_below="#id/textview_training_location"
android:textColor="#color/text_color_white" />
<TextView android:id="#+id/textview_training_cost"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toRightOf="#id/imageview_product_category"
android:layout_below="#id/textview_training_datetime"
android:textColor="#color/text_color_white" />
<TextView android:id="#+id/textview_training_registrationenddate"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toRightOf="#id/imageview_product_category"
android:layout_below="#id/textview_training_cost"
android:textColor="#color/text_color_white" />
<jacky.practice.view_custom.StarView
android:id="#+id/star_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/imageview_product_category"
android:layout_below="#id/textview_training_registrationenddate"/>
Code for custom view:
public class StarView extends View {
private Paint myPaint;
private int mLevel = 0;
public StarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public StarView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StarView(Context context) {
super(context);
init();
}
private void init()
{
myPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
myPaint.setColor(Color.GREEN);
}
public void setExpensive(int level)
{
mLevel = level;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mLevel <= 3)
{
canvas.drawCircle(20, 20, 8, myPaint);
}
else if((mLevel > 3) && (mLevel <= 5))
{
canvas.drawCircle(20, 20, 8, myPaint);
canvas.drawCircle(40, 20, 8, myPaint);
}
else
{
canvas.drawCircle(20, 20, 8, myPaint);
canvas.drawCircle(40, 20, 8, myPaint);
canvas.drawCircle(60, 20, 8, myPaint);
}
canvas.restore();
}
}
Have you forgotten to implement onCreateView?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, null);
return view;
}
padding does not work as expected in custom ViewGroup
Hi:
My layout have the following structure:
RelativeLayout(with padding)
MainView(ViewGroup)
And the activety_main.xml:
<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"
android:background="#ffffff"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".MainActivity" >
<com.example.testandroid.MainView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
MainView:
public class MainView extends ViewGroup {
public MainView(Context context, AttributeSet as) {
super(context);
addView(new MyView(context, null));
}
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawColor(Color.GREEN);
super.dispatchDraw(canvas);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0, len = getChildCount(); i < len; i++) {
View v = getChildAt(i);
v.layout(l,t,r,b);
}
}
}
MyView:
public class MyView extends SurfaceView implements Callback {
public MyView(Context contex, AttributeSet as) {
super(contex, as);
getHolder().addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refresh();
}
private void refresh() {
SurfaceHolder holder = getHolder();
synchronized (holder) {
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
try {
Paint p = new Paint();
p.setColor(Color.RED);
canvas.drawCircle(10, 10, 10, p);
} finally {
holder.unlockCanvasAndPost(canvas);
}
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
refresh();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
Now, this is what I got now:
As you can see, the viewgroup I created MainView has a background of green.
And MainView add a MyView dynamically whose background is black here.
Now, the problem is that what the MyView have a padding relative to MainView? Because I want it take all the space of MainView, that's to say, the greed should be invisible.
Why?
But
When you layout your children, it needs to be relative to your position.
To fill yourself you would do child.layout(0, 0, getWidth(), getHeight());.
Try doing this ...
<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"
android:layout_margin="16dp"
tools:context=".MainActivity" >
<com.example.testandroid.MainView
android:layout_width="match_parent"
android:layout_height="600dp"
/>
</RelativeLayout>
I am having trouble putting all the pieces together. I have 3 classes: DefaultActivity that extends Activity, MyView that extends SurfaceView, and ResistorView that extends a View.
What I want to know is how draw a resistor every time I click the button bAddResistor from the DefaultActivity class? Here are some parts from the 3 classes:
DefaultActivity.java
public class DefaultActivity extends Activity {
//MyView myView;
TextView myText;
ResistorView myResistor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//myView = (MyView) findViewById(R.id.my_view);
//myView = new MyView(this, null);
//myResistor = new ResistorView(this);
//myView.setBackgroundColor(Color.WHITE);
//myView.setScrollContainer(true);
setContentView(R.layout.main);
final Button bAddResistor = (Button) findViewById(R.id.bAdd);
bAddResistor.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
Global.numberOfResistors++;
Log.d("ButtonADD", "Button Add has been clicked");
}
});
}
}
MyView.java
public class MyView extends SurfaceView implements SurfaceHolder.Callback {
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas();
onDraw(c);
holder.unlockCanvasAndPost(c);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
ResistorView.java
public class ResistorView extends View {
private Path mSymbol;
private Paint mPaint;
//...Override Constructors...
public ResistorView(Context context) {
super(context);
init();
}
public ResistorView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mSymbol = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(2);
mPaint.setColor(-7829368);
mPaint.setStyle(Paint.Style.STROKE);
//...Your code here to set up the path,
//...allocate objects here, never in the drawing code.
mSymbol.moveTo(0.0F, 0.0F);
mSymbol.lineTo(0.0F, 50.0F);
mSymbol.lineTo(16.666666F, 58.333332F);
mSymbol.lineTo(-16.666666F, 75.0F);
mSymbol.lineTo(16.666666F, 91.666664F);
mSymbol.lineTo(-16.666666F, 108.33333F);
mSymbol.lineTo(16.666666F, 124.99999F);
mSymbol.lineTo(-16.666666F, 141.66666F);
mSymbol.lineTo(0.0F, 150.0F);
mSymbol.lineTo(0.0F, 200.0F);
mSymbol.offset(100.0F, 20.0F);
}
//...Override onMeasure()...
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Use this method to tell Android how big your view is
setMeasuredDimension(50, 50);
}
//...Override onDraw()...
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mSymbol, mPaint);
}
}
and the main.xml layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/RelativeLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:ignore="HardcodedText" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RightLayout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:background="#00000000"
android:orientation="vertical" >
<Button
android:id="#+id/bAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add RES" />
<Button
android:id="#+id/bDeleate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Del RES" />
</LinearLayout>
<com.defaul.android.MyView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_toLeftOf="#id/RightLayout"
android:background="#ff000000" />
</RelativeLayout>
If I put the drawing code in MyView.onDraw it works fine, the resistor is drawn. What I want is to click a button and draw the resistor on the surface, so every time I click I want a resistor to be added to the surface view.
Probably I'm approaching this problem in the opposite direction. If anyone can point me in the right direction I would really appreciated it.
Since I could not find a way to do what I wanted with SurfaceView I just created a class that extends View and then just add that view to my main layout.
In case it might help someone, below is a simplified version of my code:
public class CircuitSolverActivity extends Activity {
/** Called when the activity is first created. */
RelativeLayout mLayout;
MyView mView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLayout = (RelativeLayout)findViewById(R.id.elementContainer);
}
public void bAddView(View view){
mView = new MyView(context);
mView.setBackgroundColor(Color.TRANSPARENT);
mLayout.addView(mView);
}
MyView class:
public class ResistorView extends View {
public ResistorView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ResistorView(Context context){
super(context);
init();
}
private void init() {
mSymbol = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(2);
mPaint.setColor(-7829368);
mPaint.setStyle(Paint.Style.STROKE);
mSymbol.moveTo(0.0F, 0.0F);
mSymbol.lineTo(0.0F, 50.0F);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mSymbol, mPaint);
}