Set Edittext dynamically from spinner - android

I have a spinner and it has items 1,2,3 and so on.And on selection of a particular item in spinner edittexts should appear dynamically depending on the number from spinner.
If i select 3 from the drop down, i am getting three edittexts dynamically but once again if i select 2 its not displaying 2 edittexts...kindly help me to resolve.
I have attached my code..
package com.example.spinner;
import static android.view.ViewGroup.LayoutParams.FILL_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.widget.LinearLayout.VERTICAL;
import java.util.ArrayList;
import java.util.List;
import android.R.integer;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Spinner;
public class spin_activity extends Activity {
private Spinner sp;
EditText et1, et2;
List<String> list;
RelativeLayout rl;
boolean isspinnerselected = false;
private List<EditText> editTextList = new ArrayList<EditText>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spinner);
rl = (RelativeLayout) findViewById(R.id.r1);
System.out.println("####################################");
setitem();
}
private void setitem() {
/*
* sp =(Spinner)findViewById(R.id.spinner1);
*
*
*
* ArrayAdapter<CharSequence> data =
* ArrayAdapter.createFromResource(getApplicationContext(),
* R.array.Fruits, android.R.layout.simple_spinner_item);
* data.setDropDownViewResource
* (android.R.layout.simple_spinner_dropdown_item); sp.setAdapter(data);
* sp.setOnItemSelectedListener(this);
*/
sp = (Spinner) findViewById(R.id.spinner1);
list = new ArrayList<String>();
list.add("How many kids?");
list.add("1");
list.add("2");
list.add("3");
list.add("4");
ArrayAdapter<String> adp = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, list);
adp.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
sp.setAdapter(adp);
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
sp.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int pos,
long id) {
System.out.println("positoin" + pos);
if (isspinnerselected) {
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
(int) LayoutParams.WRAP_CONTENT,
(int) LayoutParams.WRAP_CONTENT);
// et1.setFocusable(true);
params.leftMargin = 80;
params.topMargin = 100;
System.out.println("Spinner selected");
int val = Integer.parseInt(sp.getSelectedItem().toString());
System.out.println("value of val" + val);
System.out.println("Child count: " + rl.getChildCount());
if (rl.getChildCount() >1 ) {
System.out.println("*************");
rl.removeViews(1, rl.getChildCount()-2);
System.out.println("Aft removng child, count is: "
+ rl.getChildCount());
}
for (int i = 0; i < val; i++)
{
System.out.println("value of i: " + i);
System.out.println("BEFORE>>>>>>Params top margin: "
+ params.topMargin);
et1 = new EditText(spin_activity.this);
et1.setFocusable(true);
et1.setLayoutParams(params);
et1.setHint("EditText" + params.topMargin);
et1.setBackgroundColor(Color.GREEN);
// et1.setLayoutParams(new
// RelativeLayout.LayoutParams(source))
rl.addView(et1);
System.out.println("Child count aft adding et: "
+ rl.getChildCount());
params.topMargin += 100;
System.out.println("AFTER>>>>>>Params top margin: "
+ params.topMargin);
}
} else
System.out.println("Spinner selected is false");
isspinnerselected = true;
/*
* et2 = new EditText (spin_activity.this);
* RelativeLayout.LayoutParams _params = new
* RelativeLayout.LayoutParams ((int) LayoutParams.WRAP_CONTENT,
* (int) LayoutParams.WRAP_CONTENT); et2.setFocusable(true);
* _params.leftMargin = 80; _params.topMargin = 280;
* et2.setLayoutParams(_params); et2.setHint("EditText");
* et2.setEms(10); rl.addView(et2);
*/
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
/*
* #Override public void onItemSelected(AdapterView<?> parent, View arg1,
* int pos, long arg3) { System.out.println("positoin"+pos);
*
* if(pos==0) { EditText et1 = new EditText (this);
* RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
* ((int) LayoutParams.WRAP_CONTENT, (int) LayoutParams.WRAP_CONTENT);
*
* params.leftMargin = 80; params.topMargin = 180;
* et1.setLayoutParams(params); et1.setHint("EditText"); et1.setEms(10); }
*
* if(pos==1) { editText("name"); }
*
*
* switch (pos) { case 0: EditText et1 = new EditText (this);
*
* RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
* ((int) LayoutParams.WRAP_CONTENT, (int) LayoutParams.WRAP_CONTENT);
*
* params.leftMargin = 80; params.topMargin = 180;
*
* et1.setLayoutParams(params);
*
* et1.setHint("EditText"); et1.setEms(10);
*
*
* break; case 1: // What ever you want to happen when item selected break;
* case 2: // What ever you want to happen when item selected break;
*
* }
*
* } private EditText editText(String hint) { EditText editText = new
* EditText(this); editText.setId(Integer.valueOf(hint));
* editText.setHint(hint); editTextList.add(editText); return editText; }
*
* #Override public void onNothingSelected(AdapterView<?> arg0) { // TODO
* Auto-generated method stub
*
* }
*/
}

Related

Drag Drawable instead of clicking by its sides to move it

I code a mini game for Android where an animal is controlled by the player when the player clicks on the sides of the Drawable.
I wonder if it is better, and if yes, how to make the Drawable touchable so that the player can drag the character to either side instead of clicking by its sides? I'm interested in both UX/UI opinion and actual solution to the problem.
package dev.android.jamie;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// An item was selected. You can retrieve the selected item using
Log.d("myTag", "This is my message" + parent.getItemAtPosition(pos));
String name = "Jamie";
String str = parent.getItemAtPosition(pos).toString();
if (str.equals("Rookie")) {
cg = new CatchGame(this, 3, name, onScoreListener);
// setContentView(cg);
mainLayout.addView(cg);
getSupportActionBar().hide();
setContentView(mainLayout);
Log.d("game", "Started Rookie game");
} else if (str.equals("Advanced")) {
mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout menuLayout = new LinearLayout(this);
menuLayout.setBackgroundColor(Color.parseColor("#FFFFFF"));
textView = new TextView(this);
textView.setVisibility(View.VISIBLE);
str = "Score: 0";
textView.setText(str);
menuLayout.addView(textView);
Button button = new Button(this);
button.setText("Pause");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePausePlay();
}
});
menuLayout.addView(button);
Spinner spinner2 = new Spinner(this);
spinner2.setOnItemSelectedListener(this);
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, spinnerValue);
spinner2.setAdapter(adapter);
menuLayout.addView(spinner2);
mainLayout.addView(menuLayout);
cg = new CatchGame(this, 5, "Jamie", onScoreListener);
cg.setBackground(getResources().getDrawable(R.drawable.bg_land_mdpi));
mainLayout.addView(cg);
// getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
getSupportActionBar().hide();
setContentView(mainLayout);
Log.d("game", "Started Advanced game");
} else if (str.equals("Expert")) {
cg = new CatchGame(this, 7, name, onScoreListener);
//setContentView(cg);
mainLayout.addView(cg);
getSupportActionBar().hide();
setContentView(mainLayout);
}
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
CatchGame cg;
public TextView textView;
public LinearLayout mainLayout;
String[] spinnerValue = {"Difficulty", "Rookie", "Advanced", "Expert", "Master"};
// start app
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout menuLayout = new LinearLayout(this);
menuLayout.setBackgroundColor(Color.parseColor("#FFFFFF"));
textView = new TextView(this);
textView.setVisibility(View.VISIBLE);
String str = "Score: 0";
textView.setText(str);
menuLayout.addView(textView);
Button button = new Button(this);
button.setText("Pause");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePausePlay();
}
});
menuLayout.addView(button);
Spinner spinner2 = new Spinner(this);
spinner2.setOnItemSelectedListener(this);
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, spinnerValue);
spinner2.setAdapter(adapter);
menuLayout.addView(spinner2);
mainLayout.addView(menuLayout);
cg = new CatchGame(this, 5, "Jamie", onScoreListener);
cg.setBackground(getResources().getDrawable(R.drawable.bg_land_mdpi));
mainLayout.addView(cg);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
getSupportActionBar().hide();
setContentView(mainLayout);
}
private void togglePausePlay() {
if (cg.paused) {
// play
// getSupportActionBar().hide();
Toast.makeText(MainActivity.this, "Play", Toast.LENGTH_SHORT).show();
} else {
// pause
// getSupportActionBar().show();
Toast.makeText(MainActivity.this, "Pause", Toast.LENGTH_SHORT).show();
}
cg.paused = !cg.paused;
}
private OnScoreListener onScoreListener = new OnScoreListener() {
#Override
public void onScore(int score) {
textView.setText("Score: " + score);
}
};
interface OnScoreListener {
void onScore(int score);
}
class CatchGame extends View {
int NBRSTEPS; // number of discrete positions in the x-dimension; must be uneven
String heroName;
int screenW;
int screenH;
int[] x; // x-coordinates for falling objects
int[] y; // y-coordinates for falling objects
int[] hero_positions; // x-coordinates for hero
Random random = new Random();
int ballW; // width of each falling object
int ballH; // height of ditto
float dY; //vertical speed
Bitmap falling, hero, jamie2, jamieleft, jamieright, falling2;
int heroXCoord;
int heroYCoord;
int xsteps;
int score;
int offset;
boolean gameOver; // default value is false
boolean toastDisplayed;
boolean paused = false;
OnScoreListener onScoreListener;
// constructor, load images and get sizes
public CatchGame(Context context, int difficulty, String name, OnScoreListener onScoreListener) {
super(context);
NBRSTEPS = difficulty;
heroName = name;
this.onScoreListener = onScoreListener;
x = new int[NBRSTEPS];
y = new int[NBRSTEPS];
hero_positions = new int[NBRSTEPS];
int resourceIdFalling = 0;
int resourceIdFalling2 = 0;
int resourceIdHero = 0;
if (heroName.equals("Jamie")) {
resourceIdFalling = R.mipmap.falling_object2;
resourceIdFalling2 = R.drawable.coconut_hdpi;
resourceIdHero = R.drawable.left_side_hdpi;
setBackground(getResources().getDrawable(R.mipmap.background));
}
falling = BitmapFactory.decodeResource(getResources(), resourceIdFalling); //load a falling image
falling2 = BitmapFactory.decodeResource(getResources(), resourceIdFalling2); //load a falling image
hero = BitmapFactory.decodeResource(getResources(), resourceIdHero); //load a hero image
jamieleft = BitmapFactory.decodeResource(getResources(), R.drawable.left_side_hdpi); //load a hero image
jamieright = BitmapFactory.decodeResource(getResources(), R.drawable.right_side_hdpi); //load a hero image
ballW = falling.getWidth();
ballH = falling.getHeight();
}
// set coordinates, etc.
void initialize() {
if (!gameOver) { // run only once, when the game is first started
int maxOffset = (NBRSTEPS - 1) / 2;
for (int i = 0; i < x.length; i++) {
int origin = (screenW / 2) + xsteps * (i - maxOffset);
x[i] = origin - (ballW / 2);
hero_positions[i] = origin - hero.getWidth();
}
int heroWidth = hero.getWidth();
int heroHeight = hero.getHeight();
hero = Bitmap.createScaledBitmap(hero, heroWidth * 2, heroHeight * 2, true);
hero = Bitmap.createScaledBitmap(hero, heroWidth * 2, heroHeight * 2, true);
jamieleft = Bitmap.createScaledBitmap(jamieleft, jamieleft.getWidth() * 2, jamieright.getWidth() * 2, true);
jamieright = Bitmap.createScaledBitmap(jamieright, jamieright.getWidth() * 2, jamieright.getWidth() * 2, true);
heroYCoord = screenH - 2 * heroHeight; // bottom of screen
}
for (int i = 0; i < y.length; i++) {
y[i] = -random.nextInt(1000); // place items randomly in vertical direction
}
offset = (NBRSTEPS - 1) / 2; // place hero at centre of the screen
heroXCoord = hero_positions[offset];
// initialize or reset global attributes
dY = 2.0f;
score = 0;
gameOver = false;
toastDisplayed = false;
}
// method called when the screen opens
#Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
screenW = w;
screenH = h;
xsteps = w / NBRSTEPS;
initialize();
}
// method called when the "game over" toast has finished displaying
void restart(Canvas canvas) {
toastDisplayed = true;
initialize();
draw(canvas);
}
// update the canvas in order to display the game action
#Override
public void onDraw(Canvas canvas) {
if (toastDisplayed) {
restart(canvas);
return;
}
super.onDraw(canvas);
int heroHeight = hero.getHeight();
int heroWidth = hero.getWidth();
int heroCentre = heroXCoord + heroWidth / 2;
Context context = this.getContext();
// compute locations of falling objects
for (int i = 0; i < y.length; i++) {
if (!paused) {
y[i] += (int) dY;
}
// if falling object hits bottom of screen
if (y[i] > (screenH - ballH) && !gameOver) {
dY = 0;
gameOver = true;
paused = true;
int duration = Toast.LENGTH_SHORT;
final Toast toast = Toast.makeText(context, "GAME OVER!\nScore: " + score, duration);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
toastDisplayed = true;
}
}, 3000);
//Vibrator v = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE);
// Vibrate for 3000 milliseconds
//v.vibrate(3000);
}
// if the hero catches a falling object
if (x[i] < heroCentre && x[i] + ballW > heroCentre &&
y[i] > screenH - ballH - heroHeight) {
y[i] = -random.nextInt(1000); // reset to new vertical position
score += 1;
onScoreListener.onScore(score);
}
}
canvas.save(); //Save the position of the canvas.
for (int i = 0; i < y.length; i++) {
if (i % 2 == 0)
canvas.drawBitmap(falling2, x[i], y[i], null); //Draw the falling on the canvas.
else
canvas.drawBitmap(falling, x[i], y[i], null); //Draw the falling on the canvas.
}
canvas.drawBitmap(hero, heroXCoord, heroYCoord, null); //Draw the hero on the canvas.
canvas.restore();
//Call the next frame.
invalidate();
}
// event listener for when the user touches the screen
#Override
public boolean onTouchEvent(MotionEvent event) {
if (paused) {
paused = false;
}
int action = MotionEventCompat.getActionMasked(event);
if (action != MotionEvent.ACTION_DOWN || gameOver) { // non-touchdown event or gameover
return true; // do nothing
}
int coordX = (int) event.getX();
int xCentre = (screenW / 2) - (hero.getWidth() / 2);
int maxOffset = hero_positions.length - 1; // can't move outside right edge of screen
int minOffset = 0; // ditto left edge of screen
if (coordX < xCentre && offset > minOffset) { // touch event left of the centre of screen
offset--; // move hero to the left
if (coordX < heroXCoord)// + heroWidth / 2)
hero = Bitmap.createScaledBitmap(jamieleft, jamieleft.getWidth(), jamieleft.getHeight(), true);
}
if (coordX > xCentre && offset < maxOffset) { // touch event right of the centre of screen
offset++; // move hero to the right
if (coordX > heroXCoord)
hero = Bitmap.createScaledBitmap(jamieright, jamieright.getWidth(), jamieright.getHeight(), true);
}
heroXCoord = hero_positions[offset];
return true;
}
}
}

Android: Speed up dynamic UI generation

I have the following class which generates a calendar view. I'm not too fond of the built-in one, and am trying to gain more control over its appearance. However rendering the new UI (e.g. upon swipe) is taking 1-2 seconds to draw. Is there any place I could speed this up? Am testing on HTC One S (2012 model)
Should be relatively straightforward to follow:
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import org.joda.time.LocalDate;
import java.util.ArrayList;
public class Calendar extends AppCompatActivity {
private LocalDate _currentSelectedDate = new LocalDate();;
private LocalDate _today = new LocalDate();;
private float x1 = 0;
private float x2 = 0;
private float y1 = 0;
private float y2 = 0;
private TableLayout _tableLayout;
private RelativeLayout _relativeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
_relativeLayout = (RelativeLayout) findViewById(R.id.calendarLayout);
recreateUI(_currentSelectedDate.getYear(), _currentSelectedDate.getMonthOfYear());
}
#Override
public boolean onTouchEvent(MotionEvent touchevent)
{
switch (touchevent.getAction())
{
case MotionEvent.ACTION_DOWN:
{
x1 = touchevent.getX();
y1 = touchevent.getY();
break;
}
case MotionEvent.ACTION_UP:
{
x2 = touchevent.getX();
y2 = touchevent.getY();
// up
if (y1 > y2)
{
_currentSelectedDate = _currentSelectedDate.plusMonths(1);
recreateUI(_currentSelectedDate.getYear(), _currentSelectedDate.getMonthOfYear());
}
// down
if (y1 < y2)
{
_currentSelectedDate = _currentSelectedDate.minusMonths(1);
recreateUI(_currentSelectedDate.getYear(), _currentSelectedDate.getMonthOfYear());
}
break;
}
}
return false;
}
private void recreateUI(int year, int month)
{
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
_tableLayout = new TableLayout(this);
_tableLayout.setLayoutParams(lp);
_tableLayout.setStretchAllColumns(true);
_relativeLayout.removeAllViews();
_relativeLayout.addView(_tableLayout);
LocalDate date = new LocalDate().withYear(year).withMonthOfYear(month).dayOfMonth().withMinimumValue();
LocalDate last = date.dayOfMonth().withMaximumValue();
addMonthNameToUi(date);
addDaysNamesToUi();
addDayNumberssToUi(date, last);
}
private void addMonthNameToUi(LocalDate date) {
TableRow row = new TableRow(this);
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.FILL_PARENT);
params.span = 7;
TextView t = new TextView(this);
t.setLayoutParams(params);
t.setGravity(Gravity.CENTER);
t.setTypeface(null, Typeface.BOLD);
t.setText(date.toString("MMM yyyy"));
row.addView(t);
float d = getResources().getDisplayMetrics().density;
int margin = (int)(20 * d);
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) t.getLayoutParams();
mlp.setMargins(mlp.leftMargin, mlp.topMargin, mlp.rightMargin, margin);
_tableLayout.addView(row);
}
private void addDaysNamesToUi() {
TableRow dayNameRow = new TableRow(this);
addMonth(dayNameRow, "Mon");
addMonth(dayNameRow, "Tue");
addMonth(dayNameRow, "Wed");
addMonth(dayNameRow, "Thu");
addMonth(dayNameRow, "Fri");
addMonth(dayNameRow, "Sat");
addMonth(dayNameRow, "Sun");
_tableLayout.addView(dayNameRow);
}
private void addDayNumberssToUi(LocalDate date, LocalDate last) {
TableRow row = null;
int columnsCount = 0;
boolean firstRow = true;
while (date.isBefore(last) || date.isEqual(last)) {
if (columnsCount == 0) {
row = new TableRow(this);
_tableLayout.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, TableLayout.LayoutParams.FILL_PARENT, 1.0f));
// blank columns for days not at the start of month
if (firstRow) {
firstRow = false;
int i = 1;
for (; i < date.getDayOfWeek(); i++) {
addDayNumberToRow(row, date, "");
}
columnsCount += i - 1;
date.plusDays(i - 1);
}
}
addDayNumberToRow(row, date, String.valueOf(date.getDayOfMonth()));
date = date.plusDays(1);
columnsCount++;
if (columnsCount == 7)
columnsCount = 0;
}
while (row.getChildCount() < 7)
addDayNumberToRow(row, date, "");
}
private void addMonth(TableRow row, String month)
{
TextView t = new TextView(this);
t.setText(month);
t.setGravity(Gravity.CENTER);
t.setTypeface(null, Typeface.BOLD);
row.addView(t);
}
private void addDayNumberToRow(TableRow row, final LocalDate date, String text)
{
TextView v = new TextView(this);
v.setText(text);
v.setGravity(Gravity.CENTER);
v.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.FILL_PARENT, 1.0f));
if (date.getDayOfMonth() == _today.getDayOfMonth() && date.getMonthOfYear() == _today.getMonthOfYear() && date.getYear() == _today.getYear()) {
v.setTypeface(v.getTypeface(), Typeface.BOLD);
v.setTextSize(v.getTextSize() + 1);
}
ShapeDrawable border = new ShapeDrawable(new RectShape());
border.getPaint().setStyle(Paint.Style.STROKE);
border.getPaint().setColor(Color.BLACK);
v.setBackground(border);
row.addView(v);
}
}
Your "recreateUI" method do alot of stuff like creating new views. Avoid creating new objects by reusing those already created.
Usually calendar views are quite complex. You most likely wont achieve smooth framerate by using multiple views in such way. You would have to write custom view witch will draw itself.
Turns out a lot of the slowdown was caused from running the application under debug mode -- running it normally resulted in acceptable performance.

Calling custom view from main activity.. Message in onDraw() is printed but custom view is not rendered

I have two classes - MainActivity.java and MainView.java.
I'm trying to render a custom view (defined in MainView.java) when screen is touched from the main activity.
My code is doing a funky thing. From the main page, when you touch the screen, it does NOT render the custom view I've specified in MainView.java - but still prints out a message I put in the onDraw() method, which should mean that onDraw() is being run. Why is my onDraw() method being run but its view doesn't render?
Also, both my onTouchEvent in MainActivity.java and MainView.java seems to respond at the same time, although the view I see is the only the activity_main.xml.
Please help :(
MainActivity.java
package com.example.owner.thesisapp;
import com.example.owner.thesisapp.MainView;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.media.AudioManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.media.SoundPool;
import android.view.View;
import android.graphics.Canvas;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends Activity {
private static SoundPool soundPool;
private static HashMap soundPoolMap;
private static int S1 = R.raw.a3v1;
private static int S2 = R.raw.c3v1;
private static int S3 = R.raw.dsharp3v1;
private static int S4 = R.raw.fsharp3v1;
private int soundID;
private boolean isSoundLoaded = false;
public MainView mainView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainView = (MainView) findViewById(R.id.main_view);
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
isSoundLoaded = true;
}
});
soundID = soundPool.load(this, R.raw.fsharp3v1, 1);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
if (isSoundLoaded) {
soundPool.play(soundID, 1f, 1f, 1, 0, 1f);
Log.d("Test", "Played sound");
}
mainView.postInvalidate();
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
// Keep landscape orientation
public void onConfigurationChanged(Configuration newConfig) {
// ignore orientation/keyboard change
super.onConfigurationChanged(newConfig);
}
}
MainView.java
package com.example.owner.thesisapp;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
/**
* Created by Owner on 6/1/2015.
*/
public class MainView extends View {
Bitmap stillWave;
int iy = 0;
public MainView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
stillWave = BitmapFactory.decodeResource(getResources(), R.drawable.wave);
setWillNotDraw(false);
Log.d("MAINVIEW: Is this ran?", " ");
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("Action DOWN!", " ");
iy = 0;
this.invalidate();
case MotionEvent.ACTION_MOVE:
Log.d("Action MOVE!", " ");
case MotionEvent.ACTION_UP:
Log.d("Action UP!", " ");
}
return false;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("MAINVIEW ONDRAW: Is this ran?", " ");
int width = canvas.getWidth();
int height = canvas.getHeight();
//set background
Rect wBackground = new Rect();
wBackground.set(0, 0, width, height);
Paint pBackground = new Paint();
pBackground.setStyle(Paint.Style.FILL);
pBackground.setColor(Color.BLACK);
canvas.drawRect(wBackground, pBackground);
//Log.d("garo, sero", width + " " + height);
//set Wave
Paint pWave = new Paint();
pWave.setStyle(Paint.Style.FILL_AND_STROKE);
pWave.setColor(Color.WHITE);
pWave.setStrokeWidth(10);
pWave.setStrokeCap(Paint.Cap.ROUND);
int waveFlucMin = -100;
int waveFlucMax = 100;
float[] coords = new float[width * 2];
for (int ix = 0; ix < width; ix++) {
int yoffset = waveFlucMin + (int) (Math.random() * ((waveFlucMax - waveFlucMin) + 1));
coords[2 * ix] = (float) ix;
coords[2 * ix + 1] = (float) iy + yoffset;
}
//Log.d("Coordinates x?", coords[1] + " " + coords[3] + " " + coords[5] + " " + coords[7] + " " + coords[301] + " " + coords[303] + " ");
//Log.d("Coordinates y?", coords[0] + " " + coords[2] + " " + coords[4] + " " + coords[6] + " " + coords[300] + " " + coords[302] + " ");
//Log.d("Generating?", "YES, generating forloop : " + iy);
//wait a second between each wave generation
/*
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
drawWave(coords, width, pWave, canvas);
if (iy < height) {
iy += 10;
invalidate();
} else {
//do nothing - finish onDraw() call.
}
}
private void drawWave(float[] coords, int width, Paint pWave, Canvas canvas) {
canvas.drawPoints(coords, 0, width*2, pWave);
}
}
activity_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" tools:context=".MainActivity">
<com.example.owner.thesisapp.MainView
android:id="#+id/main_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#111C64"/>
The problem is in your layout. Both your custom View and the ImagView are, since your are using a RelativeLayout, aligned to the Top left. The z order in this case put the ImageView on top on your custom View and, since it is taking the whole screen, you can't see your custom view.

Pull to refresh in Android without popular library

I want to implement pull-to-refresh in Android app, but I don't want to use pull-to-refresh library which is available on the internet because it is too slow for the gridView I am using. So I want to implement it by hand, do you know how to do this? Or which methods should I use from GridView?
PullRefreshContainerView.java
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
/**
* A container for a ListView that can be pulled to refresh.
* This will create a ListView and refresh header automatically, but you can
* customize them by using {#link #setList(ListView)} and {#link #setRefreshHeader(View, int)}
* <p>
* To use, put this where you would normally put your ListView. Since this does not extend
* ListView, you must use {#link #getList()} to modify the list or provide your own.
* <p>
* To get the actions of the list, use a {#link OnChangeStateListener} with {#link #setOnChangeStateListener(OnChangeStateListener)}.
* If you want to change how the refresh header looks, you should do it during these state changes.
*/
public class PullRefreshContainerView extends LinearLayout {
/**
* Interface for listening to when the refresh container changes state.
*/
public interface OnChangeStateListener {
/**
* Notifies a listener when the refresh view's state changes.
* #param container The container that contains the header
* #param state The state of the header. May be STATE_IDLE, STATE_READY,
* or STATE_REFRESHING.
*/
public void onChangeState(PullRefreshContainerView container, int state);
}
/**
* State of the refresh header when it is doing nothing or being pulled down slightly.
*/
public static final int STATE_IDLE = 0;
/**
* State of the refresh header when it has been pulled down but not enough to start refreshing, and
* has not yet been released.
*/
public static final int STATE_PULL = 1;
/**
* State of the refresh header when it has been pulled down enough to start refreshing, but
* has not yet been released.
*/
public static final int STATE_RELEASE = 2;
/**
* State of the refresh header when the list should be refreshing.
*/
public static final int STATE_LOADING = 3;
private LinearLayout mHeaderContainer;
private View mHeaderView;
private ListView mList;
private int mState;
private OnChangeStateListener mOnChangeStateListener;
private int REFRESH_VIEW_HEIGHT = 60;
/**
* Creates a new pull to refresh container.
*
* #param context the application context
*/
public PullRefreshContainerView(Context context) {
super(context);
init(context);
}
/**
* Creates a new pull to refresh container.
*
* #param context the application context
* #param attrs the XML attribute set
*/
public PullRefreshContainerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
/**
* Creates a new pull to refresh container.
*
* #param context the application context
* #param attrs the XML attribute set
* #param defStyle the style for this view
*/
public PullRefreshContainerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mState = STATE_IDLE; // Start out as idle.
float densityFactor = context.getResources().getDisplayMetrics().density;
REFRESH_VIEW_HEIGHT *= densityFactor;
// We don't want to see the fading edge on the container.
setVerticalFadingEdgeEnabled(false);
setVerticalScrollBarEnabled(false);
setOrientation(LinearLayout.VERTICAL);
// Set the default list and header.
mHeaderContainer = new LinearLayout(context);
addView(mHeaderContainer);
setRefreshViewHeight(1);
TextView headerView = new TextView(context);
headerView.setText("Default refresh header.");
setRefreshHeader(headerView);
ListView list = new ListView(context);
setList(list);
}
private boolean mScrollingList = true;
private float mInterceptY;
private int mLastMotionY;
#Override
public boolean dispatchTouchEvent (MotionEvent ev) {
float oldLastY = mInterceptY;
mInterceptY = ev.getY();
if (mState == STATE_LOADING) {
return super.dispatchTouchEvent(ev);
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastMotionY = (int) ev.getY();
mScrollingList = true;
return super.dispatchTouchEvent(ev);
case MotionEvent.ACTION_MOVE:
if (mList.getFirstVisiblePosition() == 0
&& (mList.getChildCount() == 0 || mList.getChildAt(0).getTop() == 0)) {
if ((mInterceptY - oldLastY > 5) || (mState == STATE_PULL) || (mState == STATE_RELEASE)) {
mScrollingList = false;
applyHeaderHeight(ev);
return true;
} else {
mScrollingList = true;
return super.dispatchTouchEvent(ev);
}
} else if (mScrollingList) {
return super.dispatchTouchEvent(ev);
} else {
return super.dispatchTouchEvent(ev);
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mState == STATE_RELEASE) {
refresh();
} else {
changeState(STATE_IDLE);
}
if (mScrollingList) {
return super.dispatchTouchEvent(ev);
} else {
return true;
}
default:
return super.dispatchTouchEvent(ev);
}
}
private void applyHeaderHeight(MotionEvent ev) {
final int historySize = ev.getHistorySize();
if (historySize > 0) {
for (int h = 0; h < historySize; h++) {
int historicalY = (int) (ev.getHistoricalY(h));
updateRefreshView(historicalY - mLastMotionY);
}
} else {
int historicalY = (int) ev.getY();
updateRefreshView(historicalY - mLastMotionY);
}
}
private void updateRefreshView(int height) {
if (height <= 0) {
return;
}
if ((REFRESH_VIEW_HEIGHT/4 <= mCurRefreshViewHeight) && (mCurRefreshViewHeight < REFRESH_VIEW_HEIGHT)) {
setRefreshViewHeight(height);
changeState(STATE_PULL);
} else if (mCurRefreshViewHeight >= REFRESH_VIEW_HEIGHT) {
if (height > REFRESH_VIEW_HEIGHT) {
height = (int) (REFRESH_VIEW_HEIGHT + (height - REFRESH_VIEW_HEIGHT) * REFRESH_VIEW_HEIGHT * 1.0f/height);
}
setRefreshViewHeight(height);
changeState(STATE_RELEASE);
} else {
setRefreshViewHeight(height);
}
}
private int mCurRefreshViewHeight = 60;
private void setRefreshViewHeight(int height) {
if (mCurRefreshViewHeight == height) {
return;
}
if (height == 1) {
mHeaderContainer.setLayoutParams(new LayoutParams(1, 1));
} else {
mHeaderContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height));
}
mCurRefreshViewHeight = height;
}
private void changeState(int state) {
switch (state) {
case STATE_IDLE:
setRefreshViewHeight(1);
break;
case STATE_PULL:
break;
case STATE_RELEASE:
break;
case STATE_LOADING:
setRefreshViewHeight(REFRESH_VIEW_HEIGHT);
break;
}
mState = state;
notifyStateChanged();
}
/**
* Sets the list to be used in this pull to refresh container.
* #param list the list to use
*/
public void setList(ListView list) {
if (mList != null) {
removeView(mList);
}
mList = list;
if (mList.getParent() != null) {
ViewGroup parent = (ViewGroup) mList.getParent();
parent.removeView(mList);
}
mList.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(mList);
}
/**
* #return the list inside this pull to refresh container
*/
public ListView getList() {
return mList;
}
/**
* Sets the view to use as the refresh header.
* <p />
* The header view is the view at the top that will show while the list
* is refreshing. Usually, this will be a simple rectangle that says "refreshing" and the like.
* <p />
*
* #param headerView the view to use as the whole header.
*/
public void setRefreshHeader(View header) {
if (mHeaderView != null) {
mHeaderContainer.removeView(mHeaderView);
}
if (header == null) {
throw new RuntimeException("Please supply a non-null header container.");
}
mHeaderContainer.addView(header, 0);
mHeaderView = header;
}
public void refresh() {
changeState(STATE_LOADING);
}
/**
* Notifies the pull-to-refresh view that the refreshing is complete.
* This will hide the refreshing header.
*/
public void completeRefresh() {
changeState(STATE_IDLE);
}
/**
* Notifies the listener that the state has changed.
*/
private void notifyStateChanged() {
if (mOnChangeStateListener != null) {
mOnChangeStateListener.onChangeState(this, mState);
}
}
/**
* #param listener the listener to be notified when the header state should change
*/
public void setOnChangeStateListener(OnChangeStateListener listener) {
mOnChangeStateListener = listener;
}
}
How To use
UsageDemoActivity.java
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import com.dmobile.pulltorefresh.PullRefreshContainerView.OnChangeStateListener;
import com.dmobile.pulltorefresh.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class UsageDemoActivity extends Activity {
private PullRefreshContainerView mContainerView;
private TextView mRefreshHeader;
private ListView mList;
private ArrayList<String> mStrings = new ArrayList<String>();
private ArrayAdapter<String> mAdapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mRefreshHeader = new TextView(this);
mRefreshHeader.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
mRefreshHeader.setGravity(Gravity.CENTER);
mRefreshHeader.setText("Pull to refresh...");
mContainerView = (PullRefreshContainerView) findViewById(R.id.container);
mContainerView.setRefreshHeader(mRefreshHeader);
mContainerView.setOnChangeStateListener(new OnChangeStateListener() {
#Override
public void onChangeState(PullRefreshContainerView container, int state) {
switch (state) {
case PullRefreshContainerView.STATE_IDLE:
case PullRefreshContainerView.STATE_PULL:
mRefreshHeader.setText("Pull to refresh...");
break;
case PullRefreshContainerView.STATE_RELEASE:
mRefreshHeader.setText("Release to refresh...");
break;
case PullRefreshContainerView.STATE_LOADING:
mRefreshHeader.setText("Loading...");
final Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
UsageDemoActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
addStrings(1);
mContainerView.completeRefresh();
t.cancel();
}
});
}
}, 5000, 5000);
break;
}
}
});
mList = mContainerView.getList();
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings);
mList.setAdapter(mAdapter);
addStrings(3);
}
private void addStrings(int count) {
int curSize = mStrings.size();
for (int i = 0; i < count; ++i) {
mStrings.add("String " + (curSize + i));
}
mAdapter.notifyDataSetChanged();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.dmobile.pulltorefresh.PullRefreshContainerView
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
UPDATE TO WORK WITH GRIDVIEW
PullRefreshContainerView.java
private void init(Context context) {
mState = STATE_IDLE; // Start out as idle.
float densityFactor = context.getResources().getDisplayMetrics().density;
REFRESH_VIEW_HEIGHT *= densityFactor;
// We don't want to see the fading edge on the container.
setVerticalFadingEdgeEnabled(false);
setVerticalScrollBarEnabled(false);
setOrientation(LinearLayout.VERTICAL);
// Set the default list and header.
mHeaderContainer = new LinearLayout(context);
addView(mHeaderContainer);
setRefreshViewHeight(1);
TextView headerView = new TextView(context);
headerView.setText("Default refresh header.");
setRefreshHeader(headerView);
GridView grid = new GridView(context);
setList(grid);
}
And also make related change in setListMethod();

achartengine toScreenPoint(double) always returns nullPointerException

Every time I call this method it return nullpointerexception:
java.lang.NullPointerException at org.achartengine.chart.XYChart.toScreenPoint(XYChart.java:867)
I see mScreenR of chart is null
Without using this method toScreenPoint(double) the charts works well this is the code:
package com.insights.insights.gui;
import java.util.ArrayList;
import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.LineChart;
import org.achartengine.chart.PointStyle;
import org.achartengine.chart.XYChart;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import com.insights.insights.R;
import com.insights.insights.local.ApplicationsController;
import com.insights.insights.model.AppMetrics;
import com.insights.insights.model.Application;
import com.insights.insights.model.Applications;
import com.insights.insights.model.Day;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsoluteLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
public class ChartFragment extends Fragment {
private XYMultipleSeriesRenderer renderer;
private XYMultipleSeriesDataset dataset;
private GraphicalView graphicalView;
private XYSeries firstSeries;
private XYChart chart=null;
private String apiKey;
private ArrayList<Day> days;
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
apiKey = getArguments().getString(getString(R.string.tabs_activity_api_key));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.chart_fragment, container, false);
v.findViewById(R.idChartFragment.container).requestFocus();
this.view = v;
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Obtaining data to plot
Applications applications = ApplicationsController.getInstance(getActivity()).getApplications();
ArrayList<Application> applicationArray = applications.getApplication();
if (applicationArray != null && !applicationArray.isEmpty()) {
for (int i = 0; i < applicationArray.size(); i++) {
if (applicationArray.get(i).getApiKey().equals(apiKey)) {
ArrayList<AppMetrics> appMetrics = applicationArray.get(i).getAppMetrics();
for (int j = 0; j < appMetrics.size(); j++) {
if (appMetrics.get(j).getMetric().equals("Sessions")) {
days = appMetrics.get(j).getDay();
break;
}
}
}
}
}
// If there isn't any item to plot and show a toast
if (days == null) {
Toast toast = Toast.makeText(getActivity(), R.string.chart_fragment_no_items, Toast.LENGTH_LONG);
toast.show();
return;
}
// Ploting the items
dataset = getDataset(days);
renderer = getRenderer();
setRendererStyling(renderer);
// add plot to the layout
if (graphicalView == null) {
LinearLayout layout = (LinearLayout) view.findViewById(R.idChartFragment.Chart);
chart= new LineChart(dataset, renderer);
graphicalView = new GraphicalView(getActivity(), chart);
renderer.setSelectableBuffer(11);
layout.addView(graphicalView);
} else{
graphicalView.repaint();
}
if(chart!=null&&firstSeries!=null){
for(int i=0;i<firstSeries.getItemCount();i++){
double x = firstSeries.getX(i);
double y = firstSeries.getY(i);
double[] screenPoint = chart.toScreenPoint(new double[] { x, y },0);
Log.i("puntos", x + "," + y + " = "+" ("+screenPoint[0]+", "+screenPoint[1]+")");
}
}
}
/**
* Method for set the style of the plotter window and the string at the x
* axis
*
* #param mRenderer
* render to put style in
*
* #param dataSetX
* string to set at x axis
*/
private void setRendererStyling(XYMultipleSeriesRenderer mRenderer) {
mRenderer.setApplyBackgroundColor(false);
mRenderer.setMarginsColor(R.drawable.transperent_color);
mRenderer.setMargins(new int[] { 0, 0, 0, 0 });
mRenderer.setShowAxes(false);
mRenderer.setZoomButtonsVisible(false);
mRenderer.setExternalZoomEnabled(false);
mRenderer.setPointSize(20);
mRenderer.setClickEnabled(false);
mRenderer.setDisplayValues(false);
mRenderer.setXLabels(0);
mRenderer.setYLabels(0);
mRenderer.setPanEnabled(false);
mRenderer.setZoomEnabled(false);
mRenderer.setShowLegend(false);
}
/**
* Method to introduce the values of the y axis
*
* #param dataSetY
* data to set at axis y
* #return the data to set
*/
private XYMultipleSeriesDataset getDataset(ArrayList<Day> days) {
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
firstSeries = new XYSeries("");
for (int i = 0; i < 12; i++) {
int value = Integer.parseInt(days.get(days.size() - (13 - i)).getValue());
firstSeries.add(i, value);
}
dataset.addSeries(firstSeries);
return dataset;
}
/**
* Method for set the style of the line you want to plot and create a new
* renderer
*
* #return the renderer
*/
private XYMultipleSeriesRenderer getRenderer() {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(getResources().getColor(R.color.grey_number_label_background));
r.setLineWidth(getResources().getInteger(R.integer.chart_fragment_line_width));
// r.setDisplayChartValues(true);
r.setPointStyle(PointStyle.POINT);
r.setFillPoints(true);
renderer.addSeriesRenderer(r);
return renderer;
}
}
And this is the layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+idChartFragment/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<LinearLayout
android:id="#+idChartFragment/Chart"
android:layout_width="300dp"
android:layout_height="300dp"
android:orientation="horizontal"/>
<AbsoluteLayout
android:id="#+idChartFragment/absolute"
android:layout_width="300dp"
android:layout_height="300dp"/>
</RelativeLayout>
Second Edit:
I want to do something like this:
With my code I do this:
This is my code:
package com.insights.insights.gui;
import java.util.ArrayList;
import java.util.List;
import org.achartengine.GraphicalView;
import org.achartengine.chart.ClickableArea;
import org.achartengine.chart.LineChart;
import org.achartengine.chart.PointStyle;
import org.achartengine.chart.XYChart;
import org.achartengine.model.SeriesSelection;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Layout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AbsoluteLayout;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.maps.ItemizedOverlay.OnFocusChangeListener;
import com.insights.insights.R;
import com.insights.insights.local.ApplicationsController;
import com.insights.insights.model.AppMetrics;
import com.insights.insights.model.Application;
import com.insights.insights.model.Applications;
import com.insights.insights.model.Day;
/**
*
* #author Manuel Plazas Palacio
*
*/
public class ChartFragment extends Fragment {
private XYMultipleSeriesRenderer renderer;
private XYMultipleSeriesDataset dataset;
private GraphicalView graphicalView;
private XYSeries firstSeries;
private XYChart chart = null;
private AbsoluteLayout absoluteLayout;
private ImageView point;
private LinearLayout pointInfoConatiner;
private TextView pointNumberText;
private TextView pointNameText;
private TextView pointDateText;
private Typeface avenirHeavy;
private Typeface avenirLight;
private String apiKey;
private String metricName;
private ArrayList<Day> days;
// The max and the min values displayed
private double max = 0;
private double min = 0;
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
apiKey = getArguments().getString(getString(R.string.tabs_activity_api_key));
metricName = "Sessions";
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.chart_fragment, container, false);
v.findViewById(R.idChartFragment.container).requestFocus();
this.view = v;
absoluteLayout = (AbsoluteLayout) v.findViewById(R.idChartFragment.absolute);
// pointInfoConatiner = (LinearLayout) v.findViewById(R.idChartFragment.pointInfoContainer);
// pointNumberText = (TextView) v.findViewById(R.idChartFragment.pointNumberText);
// pointNameText = (TextView) v.findViewById(R.idChartFragment.pointNameText);
// pointDateText = (TextView) v.findViewById(R.idChartFragment.pointDateText);
//
// pointNameText.setText(metricName);
// Obtaining data to plot
Applications applications = ApplicationsController.getInstance(getActivity()).getApplications();
ArrayList<Application> applicationArray = applications.getApplication();
if (applicationArray != null && !applicationArray.isEmpty()) {
for (int i = 0; i < applicationArray.size(); i++) {
if (applicationArray.get(i).getApiKey().equals(apiKey)) {
ArrayList<AppMetrics> appMetrics = applicationArray.get(i).getAppMetrics();
for (int j = 0; j < appMetrics.size(); j++) {
if (appMetrics.get(j).getMetric().equals(metricName)) {
days = appMetrics.get(j).getDay();
break;
}
}
}
}
}
// If there isn't any item to plot and show a toast
if (days == null) {
Toast toast = Toast.makeText(getActivity(), R.string.chart_fragment_no_items, Toast.LENGTH_LONG);
toast.show();
}
// Ploting the items
dataset = getDataset(days);
renderer = getRenderer();
setRendererStyling(renderer);
// add plot to the layout
if (graphicalView == null) {
LinearLayout layout = (LinearLayout) view.findViewById(R.idChartFragment.Chart);
chart = new LineChart(dataset, renderer);
graphicalView = new GraphicalView(getActivity(), chart);
renderer.setSelectableBuffer(11);
layout.addView(graphicalView);
} else {
graphicalView.repaint();
}
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
avenirHeavy = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Avenir Heavy.ttf");
avenirLight = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Avenir Light.ttf");
graphicalView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SeriesSelection seriesSelection = graphicalView.getCurrentSeriesAndPoint();
double[] xy = graphicalView.toRealPoint(0);
//creating the views
createOnClickPointsView();
if (seriesSelection != null) {
// debug
Log.d("Punto", seriesSelection.getXValue() + ", " + seriesSelection.getValue());
double x = firstSeries.getX(seriesSelection.getPointIndex() + 1);
double y = firstSeries.getY(seriesSelection.getPointIndex() + 1);
double[] screenPoint = chart.toScreenPoint(new double[] { x, y });
// debug
Log.d("Chart point", "Chart element in series index " + seriesSelection.getSeriesIndex() + " data point index "
+ seriesSelection.getPointIndex() + " was clicked" + " closest point value X=" + seriesSelection.getXValue()
+ ", Y=" + seriesSelection.getValue() + " clicked point value X=" + (float) xy[0] + ", Y=" + (float) xy[1]);
Log.d("Punto pantalla", " (" + screenPoint[0] + ", " + screenPoint[1] + ")");
int value = Integer.parseInt(days.get((int) (days.size() - (13 - x))).getValue());
String date = days.get((int) (days.size() - (13 - x))).getDate();
pointNumberText.setText(value + "");
pointDateText.setText(date);
// drawing point info
absoluteLayout.addView(pointInfoConatiner, new LayoutParams(getResources().getDrawable(R.drawable.graficapin)
.getIntrinsicWidth(), getResources().getDrawable(R.drawable.graficapin).getIntrinsicHeight(),
(int) (screenPoint[0] - (getResources().getDrawable(R.drawable.graficapin).getIntrinsicWidth() / 2)),
(int) (screenPoint[1] - (getResources().getDrawable(R.drawable.graficapin).getIntrinsicHeight()))));
// drawing point clicked
absoluteLayout.addView(point, new LayoutParams(getResources().getDrawable(R.drawable.puntoon).getIntrinsicWidth(),
getResources().getDrawable(R.drawable.puntoon).getIntrinsicHeight(), (int) (screenPoint[0] - (getResources()
.getDrawable(R.drawable.puntoon).getIntrinsicWidth() / 2)), (int) (screenPoint[1] - ((getResources()
.getDrawable(R.drawable.puntoon).getIntrinsicHeight()) / 4))));
}
}
});
}
/**
* Method for set the style of the plotter window and the string at the x
* axis
*
* #param mRenderer
* render to put style in
*
* #param dataSetX
* string to set at x axis
*/
private void setRendererStyling(XYMultipleSeriesRenderer mRenderer) {
mRenderer.setApplyBackgroundColor(false);
mRenderer.setMarginsColor(R.drawable.transperent_color);
mRenderer.setMargins(new int[] { 0, 0, 0, 0 });
mRenderer.setShowAxes(false);
mRenderer.setZoomButtonsVisible(false);
mRenderer.setExternalZoomEnabled(false);
mRenderer.setPointSize(getResources().getInteger(R.integer.chart_fragment_point_size));
mRenderer.setClickEnabled(true);
mRenderer.setDisplayValues(false);
mRenderer.setXLabels(0);
mRenderer.setYLabels(0);
mRenderer.setPanEnabled(true);
mRenderer.setZoomEnabled(false);
mRenderer.setShowLegend(false);
mRenderer.setYAxisMax(max + 10);
mRenderer.setYAxisMin(min - 10);
}
/**
* Method to introduce the values of the y axis
*
* #param dataSetY
* data to set at axis y
* #return the data to set
*/
private XYMultipleSeriesDataset getDataset(ArrayList<Day> days) {
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
firstSeries = new XYSeries("");
for (int i = 0; i < 12; i++) {
int value = Integer.parseInt(days.get(days.size() - (13 - i)).getValue());
firstSeries.add(i, value);
}
dataset.addSeries(firstSeries);
XYSeries secondSeries = new XYSeries("");
for (int i = 1; i < 11; i++) {
int value = Integer.parseInt(days.get(days.size() - (13 - i)).getValue());
if (i == 1) {
max = value;
min = value;
}
if (value > max)
max = value;
if (value < min)
min = value;
secondSeries.add(i, value);
}
dataset.addSeries(secondSeries);
return dataset;
}
/**
* Method for set the style of the line you want to plot and create a new
* renderer
*
* #return the renderer
*/
private XYMultipleSeriesRenderer getRenderer() {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
//First chart with the line
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(getResources().getColor(R.color.grey_number_label_background));
r.setLineWidth(getResources().getInteger(R.integer.chart_fragment_line_width));
// r.setDisplayChartValues(true);
r.setPointStyle(PointStyle.POINT);
r.setFillPoints(true);
renderer.addSeriesRenderer(r);
// Second chart with the points
XYSeriesRenderer r1 = new XYSeriesRenderer();
r1.setColor(getResources().getColor(R.color.purple_chart_points));
r1.setLineWidth(0);
r1.setFillPoints(true);
r1.setPointStyle(PointStyle.CIRCLE);
renderer.addSeriesRenderer(r1);
return renderer;
}
public XYSeries getFirstSeries() {
return firstSeries;
}
public void setFirstSeries(XYSeries firstSeries) {
this.firstSeries = firstSeries;
}
public XYChart getChart() {
return chart;
}
public void setChart(XYChart chart) {
this.chart = chart;
}
/**
* Method for create the views when clicking on a point of the chart
*/
private void createOnClickPointsView() {
//If the info is already visible
if (pointInfoConatiner != null)
absoluteLayout.removeView(pointInfoConatiner);
// If the point is drawn
if (point != null)
absoluteLayout.removeView(point);
pointInfoConatiner = new LinearLayout(getActivity());
pointInfoConatiner.setBackgroundDrawable(getResources().getDrawable(R.drawable.graficapin));
pointInfoConatiner.setOrientation(LinearLayout.VERTICAL);
pointInfoConatiner.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 8, 0, 0);
pointNumberText = new TextView(getActivity());
pointNumberText.setTextSize(18);
pointNumberText.setTextColor(getResources().getColor(R.color.purple_chart_points));
pointNumberText.setTypeface(avenirHeavy);
pointNumberText.setGravity(Gravity.CENTER);
pointNameText = new TextView(getActivity());
pointNameText.setTextSize(18);
pointNameText.setTextColor(getResources().getColor(R.color.grey_users_label));
pointNameText.setTypeface(avenirLight);
pointNameText.setText(metricName);
pointNameText.setGravity(Gravity.CENTER);
pointDateText = new TextView(getActivity());
pointDateText.setTextSize(11);
pointDateText.setTextColor(getResources().getColor(R.color.grey_users_label));
pointDateText.setTypeface(avenirHeavy);
pointDateText.setGravity(Gravity.CENTER);
pointInfoConatiner.addView(pointNumberText, 0, layoutParams);
layoutParams.setMargins(0, 2, 0, 0);
pointInfoConatiner.addView(pointNameText, 1, layoutParams);
pointInfoConatiner.addView(pointDateText, 2, layoutParams);
point = new ImageView(getActivity());
point.setImageDrawable(getResources().getDrawable(R.drawable.puntoon));
}
}
Anyone know how can I:
1-Quit the bottom border
2-Quit the line of the pink chart
3-The chart don't move when I touch the points
4- When I ask for the screen point why to many times the y value returns infinite
There used to be this bug in an older version of AChartEngine. I suggest you update to 1.1.0.
Also, please note that the chart must have been already displayed when calling the method. If the chart didn't display on screen then there is no way to calculate that.

Categories

Resources