I'm trying to make some graphics in my application with the AchartEngine API but it doesn't works.
Can anyone explain me how to have a view with a graphic instead of Intent?
Cause in the demo code it's only by Intent, not by view.
edit:
I tried to test the 2 options at the same time:
I have a linearLayout with a button in it:
<LinearLayout android:id="#+id/list_infos_layout_stat" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" >
<Button
android:id="#+id/list_infos_bouton_stats"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="statistiques"
/>
When I hit the button, a new activity is made by the ChartFactory.getLineChartIntent(..) method and it works great.
And in the same LinearLayout, I put a view returned by ChartFactory.getLineChartView method, its ok I have the graphic at the right of the button.
But when I remove the button I have nothing...
View graphique = new ReponsesChart().getView(contexte);
if (graphique !=null){
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.list_infos_layout_stat);
layout.addView(graphique, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
} else {
Log.d("Infos", "GRAPHIQUE NULL");
}
edit 2: Fixed by replacing Fill Parent properties when I add the view to the layout by the width of the screen
In the ChartFactory class there are several methods that you can use like this:
GraphicalView gView=ChartFactory.getDoughnutChartView(context,data,renderer);
and similar ones for other graph types like line charts and bar charts. You can then simply call:
setContentView(gView);
Download the documentation for AChartEngine, its pretty easy to find there.
Would something that writes to a bitmap help? I use the following in some of my code:
final XYMultipleSeriesRenderer multipleRenderer = new XYMultipleSeriesRenderer();
final XYSeriesRenderer renderer = new XYSeriesRenderer();
multipleRenderer.addSeriesRenderer(renderer);
final XYMultipleSeriesDataset dataset = final XYMultipleSeriesDataset dataset = ...
final Bitmap image1 = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
final TimeChart tc = new TimeChart(dataset, multipleRenderer);
final Canvas canvas = new Canvas(image1);
tc.draw(canvas, 0, 0, WIDTH, HEIGHT, paint);
final Bitmap image = Bitmap.createBitmap(image1, 0, 0, WIDTH, HEIGHT);
Note that I've cut out a lot of code relating to initialising the multipleRender and dataset
Related
I'm trying to add multiple customo views (for now they are simple rectangles) using this code
//Defining the layout
HandLayout = new LinearLayout(this);
HandLayout.setOrientation(LinearLayout.HORIZONTAL);
HandLayout.setBackgroundColor(getResources().getColor(R.color.bg_hand));
HandLayout.setLayoutParams(new LayoutParams(getResources().getInteger(R.integer.dim_hand_width), getResources().getInteger(R.integer.dim_hand_height)));
//Some more code
int dx = getResources().getInteger(R.integer.dim_cardslot_width);
for (int i = 0; i < 6; i++){
Card c = new Card(this,i);
HandLayout.addView(c);
c.setX(i*dx);
}
The problem is that instead of getting 6 rectagles one next to the other I only see the first rectangle.
I think the rectangles are there but are "behind" the first drawn rectangle. How do I tell the view to "move" them dx to the right?
Thanks for any help
EDIT: The problem is with the Card Class code, I think. After a suggestion from one of the user I've tried adding TextViews and they worked. Here is the code for the card class (NOTE the only code not present are the declarations of a bunch of constant ints).
public Card(Context context, int id) {
super(context);
// TODO Auto-generated constructor stub
borders = new Rect(0,0,
getResources().getInteger(R.integer.dim_cardslot_width),
getResources().getInteger(R.integer.dim_cardslot_height));
offw = (getResources().getInteger(R.integer.dim_cardslot_width) - getResources().getInteger(R.integer.dim_card_width))/2;
offh = (getResources().getInteger(R.integer.dim_cardslot_height) - getResources().getInteger(R.integer.dim_card_height))/2;
cborders = new RectF((float)offw, (float)offh,
(float)getResources().getInteger(R.integer.dim_card_width),
(float)getResources().getInteger(R.integer.dim_card_height));
ntext = Typeface.create(Typeface.MONOSPACE,Typeface.NORMAL);
paint = new Paint();
}
protected void onDraw(Canvas canvas){
paint.setColor(getResources().getColor(R.color.bg_card));
canvas.drawRect(borders, paint);
paint.setColor(getResources().getColor(R.color.main_card));
canvas.drawRoundRect(cborders, rad, rad, paint);
paint.setColor(getResources().getColor(R.color.card_text));
paint.setTextSize(14);
canvas.drawText("Card: " + String.valueOf(ID),offw,TopOffset+CharHeight,paint);
}
They are not "behind", they are "next" to each other, the width of every view i think is fill_parent this is why you get only one view, try to put your parent layout inside a scrollView and check the difference
XML solution:
Let's say your card design is represented as follows
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
in your java code:
for (int i = 0; i < 6; i++){
View cardView = LayoutInflater.from(getActivity()).inflate(R.layout.xml_above, null);
TextView tv = cardView.findViewById(R.id.value));
tv.setText("your text");
//if you have click listeners
tv.setOnClickListener(...);
HandLayout.addView(cardView);
}
as simple as it looks
I want to create my entire app's UI using Droid.Dialog in MvvmCross. More specifically setting the background image and then adding a header image to the view, as well as input fields and buttons.
I am stuck trying to get a header image into the view. Firstly here is a wireframe explaining what I mean by header image:
I have managed to set the background gradient image using:
using (var drawable = Resources.GetDrawable(Resource.Drawable.Backgroud))
Window.SetBackgroundDrawable(drawable);
I have then tried to add the header image using the Cirrious.MvvmCross.Dialog.Droid stuff like this:
var img = new ImageView(this.BaseContext);
img.LayoutParameters = new Gallery.LayoutParams(330, 110);
img.SetImageResource(Resource.Drawable.Header);
Root = new RootElement()
{
new Section(){new ImageElement(img)}
};
However, the image appears as a tiny blotch in the UI.
Doing this in AXML I would set the image as follows:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerInParent="true"
android:orientation="vertical">
<ImageView
android:layout_width="330dp"
android:layout_height="110dp"
android:src="#drawable/Header" />
</LinearLayout>
I'm basically stuck trying to figure out how to get the image into the view at the top of the screen and with the right dimensions!
Any help would be greatly appreciated. Or am I better off creating the views using the native AXML and IB respectively?
If you look what is inside the ImageElement and what happens when you call the ctor with the ImageView argument, then you will discover that the image is scaled to 48x44.
https://github.com/MvvmCross/MvvmCross/blob/v3/CrossUI/CrossUI.Droid/Dialog/Elements/ImageElement.cs#L52:
private const int dimx = 48;
private const int dimy = 44;
...
private ImageView Scale(ImageView source)
{
var drawable = (BitmapDrawable) source.Drawable;
var bitmap = drawable.Bitmap;
var bMapScaled = Bitmap.CreateScaledBitmap(bitmap, dimx, dimy, true);
source.SetImageBitmap(bMapScaled);
return source;
}
So you have a couple of options:
Create your own Element, where you are in the control of what is done with the ImageView
Do it by creating a native Android Layout instead.
So I'm creating a board game that uses a 9x9 board with different images for the edges/corners and the middle of the board. After doing a lot of research, people seem to recommend using a TableLayout with buttons or imageButtons for each individual space on the board.
What I am wondering is that in my game, the pieces can also be rotated by 45 degrees each turn. My original plan was to simply have the pieces as part of the imageButton, but I am not sure how I could rotate it. One option that I can think of would be to simply have an individual image for each 45deg rotation, but this seems extremely inefficient as it would require 8 images per piece.
Questions:
Is a tablelayout the proper way to implement my board?
Should I be using imagebuttons for each space on my board?
What would be the best way to rotate my pieces? Should I use a canvas approach for the entire game?
Thank you and please let me know if anything isn't clear.
Yes table layout is a good aproach for this kind of layout IMO
If you have to push on the image you can use ImageButtons, otherwise just use ImageView.
You can rotate a drawable the following way.
private void updateImageOrientation(final float rotationAngle) {
// rotate compass to right orientation
final ImageView img = (ImageView) findViewById(R.id.actMyDrawableImage);
// only if imageView in layout
if (img != null) {
final Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.act_my_drawable);
// Getting width & height of the given image.
final int w = bmp.getWidth();
final int h = bmp.getHeight();
// Setting post rotate to rotation angle
final Matrix mtx = new Matrix();
// Log.v(LOG_TAG, "Image rotation angle: " + rotationAngle);
mtx.postRotate(rotationAngle, (float) (w / 2.0), (float) (h / 2.0));
// Rotating Bitmap
final Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
final BitmapDrawable bmd = new BitmapDrawable(getResources(), rotatedBMP);
img.setImageDrawable(bmd);
}
}
Edit 1:
To use ImageButton just replace ImageView by ImageButton in he code above.
final ImageButton img = (ImageButton) findViewById(R.id.actMyDrawableImage);
img.setImageDrawable(drawable)
Edit 2
To show your pieces above your board you could use a FrameLayout for each of your cell. The background would be set:
using an ImageView as below
with a background flag on the FrameLayout (android:background)
if you want one background for your board with a background flag on the parent TableLayout
You can make your pieces visible/invisible programatically:
img.setVisibility(View.VISIBLE);
img.setVisibility(View.INVISIBLE);
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/actMyDrawableButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible" >
</ImageView>
<ImageButton
android:id="#+id/actMyDrawableButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" >
</ImageButton>
</FrameLayout>
First i give my View show below. and give some explanation:
In my ViewGroup i have two GraphicalView, each of them share the same size space. Let's just call the chart above chartA and below one chartB.
Then i have some questions:
If i make a move a movement on chartA ,how could i make the chartB move just as my finger moving on chartB?
If i pinch on chartA can also chartB change auto?
I want to add some callback function to some points? Does ACE supports this?
I do not want to show numbers negative while user pinching.How can I make this point?
Last is my chart code:
mDataset.addSeries(series);
PointStyle style = PointStyle.CIRCLE;
renderer = buildRenderer(lineColor, style, true);
setChartSettings(renderer, "X", "Y", 0, 50, yMin, yMax, Color.WHITE,
Color.WHITE, title,chartColor);
GraphicalView chart = ChartFactory.getLineChartView(context, mDataset, renderer);
layout.addView(chart, new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
HashMap map = new HashMap();
and the renderer:
protected XYMultipleSeriesRenderer buildRenderer(int color,
PointStyle style,
boolean fill) {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(color);
r.setPointStyle(style);
r.setFillPoints(fill);
r.setLineWidth(3);
renderer.addSeriesRenderer(r);
return renderer;
}
I random all the data i want.
You have to register a PanListener on your chartA and on every panApplied event, just do: rendererB.setXAxisMin(rendererA.getXAxisMin()); and the same for max X and for the Y axis and then call chartB.repaint();
Same as the above, just that you need to add a ZoomListener.
You can set a click listener: chartA.setOnClickListener();
Please reformulate into a separate question.
Also, see this code showing you how to use the above APIs.
I have an app that displays some data graphically. It creates two Views to draw graphics in and adds them to my layout. Each view shows the data differently way but each View implements onSizeChanged() the same:
protected void onSizeChanged(int curw, int curh, int oldw, int oldh) {
if (bitmap2 != null) {
bitmap2.recycle();
}
canvas2= new Canvas();
bitmap2 = Bitmap.createBitmap(curw, curh, Bitmap.Config.ARGB_8888);
canvas2.setBitmap(bitmap2);
}
The views are invoked thusly:
LinearLayout myLayout = (LinearLayout)findViewById(R.id.revlay);
GraphView1 graphView1 = new GraphView1(this, theEventArrayList);
myLayout.addView(graphView1);
GraphView2 graphView2 = new GraphView2(this, theEventArrayList);
myLayout.addView(graphView2);
Always the first onSizeChanged() that gets called gets a height of 652 and a width of 480; the second one gets a height of 0, which causes createBitmap() to fail. If I reversed the order of the above invocation then graphView1 would fail that way. I'd like each bitmap to have about half the area.
Thanks in advance for explaining what's going on!
its difficult to answer your question without knowing further implementation details about your graphviews and the layout parameters of the LinearLayout.
But assuming your LinearLayout has a horizontal orientation try this:
GraphView1 graphView1 = new GraphView1(this, theEventArrayList);
GraphView2 graphView2 = new GraphView2(this, theEventArrayList);
myLayout.addView(graphView2, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
myLayout.addView(graphView1, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
this will tell the LinearLayout to arrange your views so that they equally divide the horizontal space between themselves.