this is my first question! I have an activity (MainActivity) and a View (PanZoomView) which can be zoomable. The Layout is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.canvastest.PanZoomView
android:id="#+id/zoomview"
android:layout_width="300dp"
android:layout_height="300dp" />
<TextView
android:id="#+id/tv_mPosX"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<TextView
android:id="#+id/tv_mPosY"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</LinearLayout>
I want to set the tv_mPosX/Y strings according to zoom factor (mScaleFactor) that is computed in the view:
public class PanZoomView extends View {
protected Drawable mSampleImage;
protected Context mContext;
protected float mPosX;
protected float mPosY;
//
public float mScaleFactor = 1.f;
...
Where/How I can handle this?
Thanks to all,
Riccardo
mScaleFactor Ok guys, I found the solution.
1) I implemented in the View object a getter
2) This is my final activity, with a Thread which updates the UI
public class MainActivity extends Activity {
private Handler frame = new Handler();
private static final int FRAME_RATE = 40; // 1000ms/40ms = 25 frames per second
private PanZoomView w;
private TextView t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
w = (PanZoomView) findViewById(R.id.zoomview);
t = (TextView) findViewById(R.id.tv_mPosX);
frame.post(frameUpdate);
}
private Runnable frameUpdate = new Runnable() {
#Override
public void run() {
t.setText("mScaleFactor =" + w.get_mScaleFactor());
frame.postDelayed(frameUpdate, FRAME_RATE);
}
};
}
Related
Context: I want to build a horizontal progress bar with some values and want to put some text that move along below this progress bar. So my final ideia is something like this (I already have the progress bar built I only left the text views below)
My current code is something like this:
This is my StackedHorizontalProgressBar class:
public class StackedHorizontalProgressBar extends ProgressBar {
private Paint paint;
int primary_progress, max_value;
public StackedHorizontalProgressBar(Context context) {
super(context);
init();
}
public StackedHorizontalProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
#Override public synchronized void setMax(int max) {
this.max_value = max;
super.setMax(max);
}
#Override public synchronized void setProgress(int progress) {
if (progress > max_value) {
progress = max_value;
}
this.primary_progress = progress;
super.setProgress(progress);
}
#Override public synchronized void setSecondaryProgress(int secondaryProgress) {
if ((primary_progress + secondaryProgress) > max_value) {
secondaryProgress = (max_value - primary_progress);
}
super.setSecondaryProgress(primary_progress + secondaryProgress);
}
private void init() {
paint = new Paint();
paint.setColor(Color.BLACK);
primary_progress = 0;
max_value = 100;
}
}
This is my Main Activity layout (that uses above class)
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<github.nisrulz.stackedhorizontalprogressbar.StackedHorizontalProgressBar
android:id="#+id/stackedhorizontalprogressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:progressDrawable="#drawable/stacked_horizontal_progress"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="16dp" />
</android.support.constraint.ConstraintLayout>
This is my MainActivity class:
public class MainActivity extends AppCompatActivity {
int max = 100;
int countPrimary = 20;
int countSecondary = 30;
StackedHorizontalProgressBar stackedHorizontalProgressBar;
TextView txt_primary, txt_secondary;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stackedHorizontalProgressBar =
(StackedHorizontalProgressBar) findViewById(R.id.stackedhorizontalprogressbar);
stackedHorizontalProgressBar.setMax(max);
stackedHorizontalProgressBar.setProgress(countPrimary);
txt_primary.setText("Primary Value : " + countPrimary + "%");
stackedHorizontalProgressBar.setSecondaryProgress(countSecondary);
txt_secondary.setText("Secondary Value : " + countSecondary + "%");
}
}
I think I must use canvas for this, so if there is anyone with experience with this that can help me.
public class ProgressBarAvtivity extends AppCompatActivity {
ProgressBar progressBar;
TextView tvProgress;
int d = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_bar_avtivity);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setProgress(d);
tvProgress = (TextView)findViewById(R.id.tvProgress);
tvProgress.setText(String.valueOf(d));
if (d > 40) {
tvProgress.setX(((width )* d / 100) - (d/2));
}
else {
tvProgress.setX(((width )* d / 100));
}
}}
I need an example of view pager with carousel effect.I've searched through internet but I couldn't find any example.So , have you done anything like this before ? Do you have any examples that I can examine.
You need:
activity_main
item
Custom Fragment
Custom LinearLayout
CustomPagerAdapter
Activity
I use this code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:attrs="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.thedeveloperworldisyours.carouselviewpager.MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/activity_main_view_pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<com.thedeveloperworldisyours.carouselviewpager.CustomLinearLayout
android:id="#+id/item_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/item_size_text" />
<Button
android:id="#+id/item_content"
android:layout_width="230dp"
android:layout_height="120dp"
android:background="#android:color/black"/>
</com.thedeveloperworldisyours.carouselviewpager.CustomLinearLayout>
</LinearLayout>
Custom Fragment
public class CustomFragment extends Fragment {
public static Fragment newInstance(Activity context, int position, float scale) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
bundle.putFloat("scale", scale);
return Fragment.instantiate(context, CustomFragment.class.getName(), bundle);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout linearLayout = (LinearLayout)
inflater.inflate(R.layout.item, container, false);
int position = this.getArguments().getInt("position");
TextView textView = (TextView) linearLayout.findViewById(R.id.item_text);
textView.setText(String.valueOf(position));
CustomLinearLayout root = (CustomLinearLayout) linearLayout.findViewById(R.id.item_root);
float scale = this.getArguments().getFloat("scale");
root.setScaleBoth(scale);
return linearLayout;
}
}
Custom LinearLayout
public class CustomLinearLayout extends LinearLayout {
private float mScale = BIG_SCALE;
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout(Context context) {
super(context);
}
public void setScaleBoth(float scale) {
this.mScale = scale;
this.invalidate(); // If you want to see the mScale every time you set
// mScale you need to have this line here,
// invalidate() function will call onDraw(Canvas)
// to redraw the view for you
}
#Override
protected void onDraw(Canvas canvas) {
// The main mechanism to display mScale animation, you can customize it
// as your needs
int w = this.getWidth();
int h = this.getHeight();
canvas.scale(mScale, mScale, w / 2, h / 2);
super.onDraw(canvas);
}
}
The most import thing is the adapter
public class CustomPagerAdapter extends FragmentPagerAdapter implements ViewPager.PageTransformer {
public final static float BIG_SCALE = 1.0f;
public final static float SMALL_SCALE = 0.7f;
public final static float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;
private Activity mContext;
private FragmentManager mFragmentManager;
private float mScale;
public CustomPagerAdapter(Activity context, FragmentManager fragmentManager) {
super(fragmentManager);
this.mFragmentManager = fragmentManager;
this.mContext = context;
}
#Override
public Fragment getItem(int position) {
// make the first mViewPager bigger than others
if (position == FIRST_PAGE)
mScale = BIG_SCALE;
else
mScale = SMALL_SCALE;
return CustomFragment.newInstance(mContext, position, mScale);
}
#Override
public int getCount() {
return PAGES;
}
#Override
public void transformPage(View page, float position) {
CustomLinearLayout myLinearLayout = (CustomLinearLayout) page.findViewById(R.id.item_root);
float scale = BIG_SCALE;
if (position > 0) {
scale = scale - position * DIFF_SCALE;
} else {
scale = scale + position * DIFF_SCALE;
}
if (scale < 0) scale = 0;
myLinearLayout.setScaleBoth(scale);
}
}
and now the Activity
public class MainActivity extends AppCompatActivity {
public final static int PAGES = 5;
public final static int FIRST_PAGE = 0 ;
public CustomPagerAdapter mAdapter;
public ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.activity_main_view_pager);
mAdapter = new CustomPagerAdapter(this, this.getSupportFragmentManager());
mViewPager.setAdapter(mAdapter);
mViewPager.setPageTransformer(false, mAdapter);
// Set current item to the middle page so we can fling to both
// directions left and right
mViewPager.setCurrentItem(FIRST_PAGE);
// Necessary or the mViewPager will only have one extra page to show
// make this at least however many pages you can see
mViewPager.setOffscreenPageLimit(3);
// Set margin for pages as a negative number, so a part of next and
// previous pages will be showed
mViewPager.setPageMargin(-400);
}
}
Also you check this Tutorial and this exmple in GitHub.
Please find the link below as solution to implement Carousel in android using View Pager:
https://github.com/haerulmuttaqin/SwipeViewPager
Hope it helps anyone looking for answers.
You can have a look at CarouselView.
Might help you if you need a simple carouselview.
Add view in your layout:
<com.synnapps.carouselview.CarouselView
android:id="#+id/carouselView"
android:layout_width="match_parent"
android:layout_height="200dp"
app:fillColor="#FFFFFFFF"
app:pageColor="#00000000"
app:radius="6dp"
app:slideInterval="3000"
app:strokeColor="#FF777777"
app:strokeWidth="1dp"/>
Add images by implementing callback:
public class SampleCarouselViewActivity extends AppCompatActivity {
CarouselView carouselView;
int[] sampleImages = {R.drawable.image_1, R.drawable.image_2, R.drawable.image_3, R.drawable.image_4, R.drawable.image_5};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_carousel_view);
carouselView = (CarouselView) findViewById(R.id.carouselView);
carouselView.setPageCount(sampleImages.length);
carouselView.setImageListener(imageListener);
}
ImageListener imageListener = new ImageListener() {
#Override
public void setImageForPosition(int position, ImageView imageView) {
imageView.setImageResource(sampleImages[position]);
}
};
}
This is my MainActivity:
public class MainActivity extends Activity {
PieMenu pieMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pieMenu = new PieMenu(getApplicationContext());
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
{
pieMenu.addPieMenu(x,y);
}
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
return false;
}
}
PieMenu:
public class PieMenu extends FrameLayout{
private Context _context;
public PieMenu(Context context) {
super(context);
_context = context;
// TODO Auto-generated constructor stub
}
public void addPieMenu(int x, int y){
Toast.makeText(_context, "text",Toast.LENGTH_LONG).show();
PieItem pieView = new PieItem(_context,x,y,2);
//FrameLayout.LayoutParams lyp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
//pieView.setLayoutParams(lyp);
addView(pieView);
invalidate();
}
}
PieItem.java:
public class PieItem extends View{
private final float x;
private final float y;
private final int r;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public PieItem(Context context, float x, float y, int r) {
super(context);
mPaint.setColor(0xFFFF0000);
this.x = x;
this.y = y;
this.r = r;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
}
MainActivity.xml:
<FrameLayout 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" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/hello_world" />
</FrameLayout>
Everytime I touch the scree, the toast is being called but the circle isn't being instantiated. Where am I going wrong?
easiest way to fix this, add view in onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pieMenu = new PieMenu(getApplicationContext());
FrameLayout fl = (FrameLayout)findViewById(R.id.layout);
fl.addView(pieMenu);
}
and add id to your main activity xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
You aren't adding pieMenu to any of the views in your layout (R.layout.activity_main)
What does your activity_main.xml look like?
You didn't add created PieMenu to activity layout. You need to call something like this in onCreate method:
view.addView(pieMenu);
Or add your PieMenu to you activity_main layout.
I'm trying to draw fractal on a SurfaceView within asynctask but I'm not sure how to perform it properly. My idea was to create surfaceview (in the main activity) which would contain progress bar, while separate thread would calculate which pixels will be drawn and store this on some kind of "buffer" (I use canvas for this). After that on the surfaceview result should be drawn (which should destroy spinning wheel of progress bar).
I've written this code:
MainActivity.java
public class MainActivity extends Activity {
private Complex constant;
private int bg_color, fg_color;
private static final int nMax = 30, rMax = 2;
private class JuliaThread extends AsyncTask<Complex, Void, Canvas> {
private double re, im, w, h;
private Complex sequence;
private int i;
private Canvas canv;
private Paint p;
private View m;
#Override
protected void onPreExecute() {
super.onPreExecute();
m = (View) findViewById(R.id.sv);
w = m.getWidth();
h = m.getHeight();
canv = new Canvas();
p = new Paint();
}
#Override
protected Canvas doInBackground(Complex... c) {
for (double y=0; y<h; y++) {
for (double x=0; x<w; x++) {
re = (x/w)*3.0-1.5;
im = -(y/h)*3.0-1.5;
sequence = new Complex(re, im);
for (i=1; i<=nMax; i++) {
sequence = sequence.square();
sequence.add(c[0]);
if (sequence.abs() > rMax) break;
}
if (i == nMax) p.setColor(fg_color);
else p.setColor(bg_color);
canv.drawLine((float)x, (float)y, (float)x, (float)y, p);
}
}
return canv;
}
#Override
protected void onPostExecute(Canvas result) {
super.onPostExecute(result);
m.draw(result);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
constant = new Complex(-0.391, -0.587);
bg_color = Color.rgb(0, 0, 0);
fg_color = Color.rgb(255, 255, 255);
new JuliaThread().execute(constant);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:id="#+id/mainview" >
<SurfaceView
android:id="#+id/sv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</SurfaceView>
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/sv"
android:layout_centerHorizontal="true"
android:layout_marginTop="138dp" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/progressBar1"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:text="#string/loading"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Unfortunately, this approach doesn't work. Could you explain me, what am I doing wrong and how to do this properly?
You first need to obtain a SurfaceHolder from SurfaceView (by implementing SurfaceHolder.Callback). Then do something like:
final Canvas c = mSurfaceHolder.lockCanvas();
//---draw stuff--
mSurfaceHolder.unlockCanvasAndPost(c);
So I'm realy confused
I am having a View(R.layout.main) which includes a custom view (canvas)
this View contains a button which is overlayed over the canvas
but when I click the button the OnClicklistener fires the event but after that button is doing nothing when clicked
Activity :
public class RunActivity extends Activity implements OnTouchListener, OnClickListener {
static int width;
static int height;
static boolean reset=false;
//draw d;
View d;
Button jump_button;
//jump
float last_touchpos=0;
static boolean jump=false;
private static Context mContext;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//d = new draw(this);
d = getLayoutInflater().inflate(R.layout.main, null);
d.setOnTouchListener(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mContext = this;
//get screen size
WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
width = display.getWidth(); // deprecated
height = display.getHeight(); // deprecated
setContentView(d);
jump_button = (Button) findViewById(R.id.jump);
jump_button.setOnClickListener(this);
}
public static Context getContext(){
return mContext;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("touch","touched");
if (draw.end == true)
{
reset=true;
}
else
{
if(last_touchpos != 0)
{
if(last_touchpos < event.getY())
{
jump = true;
last_touchpos = 0;
}
}
else
{
last_touchpos = event.getY();
}
}
return false;
}
#Override
public void onClick(View arg0) {
jump = true;
}
}
Layout :
<?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="fill_parent"
android:orientation="vertical" >
<run.alexander.fuchs.draw
android:id="#+id/canvasview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/jump"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Jump" />
</RelativeLayout>
static boolean jump=false;
remove static from this statement
boolean jump=false;
How can you sure your onClick is called once. Use a log print message within onClick method to make sure that it is called once. Your code is okay, and I hope your onClick works properly and check your rest of code.