I am new to Android and using source that makes an image float. But I want content, such as an entire layout, to float instead of image. I think I need to replace ImageView with something else and searched for some possibilities on Android Developers site but couldn't find one.
What should I use in place of ImageView and setImageResource?
Here is my code:
import android.widget.ImageView;
public class Float extends Service {
private WindowManager windowManager;
private ImageView chatHead;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.image);
...
Thanks!
Related
I have done I game in which I want to call on a method I have in a view from another view. I figured I would somehow have to send the "first view" into the "second view" through the my MainActivity in order for the second view to be able to call on the first view methods. However, I couldn't come up with any way of sending in the first view to the second view through my MainAcitivity, so I decided to change tactics. I now tried to have a function in my MainActivity to handle the interection between the views, but once again I was not able to call on the method from the second View.
Therefore my question is how do you send a view into another view through an Activity, or If that's not possible how do you call on an activity method through a view?
Here is the code (I added some comments to better show the problem I'm having):
public class MainActivity extends AppCompatActivity {
private FishView gameView;
private SmallBall smallBall ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
smallBall = new SmallBall(this);
screen.addView(gameView); // first view
screen.addView(smallBall); //second view
}
//this is the method I want to reach through the View
public void handleAvoidedBall(){
gameView.avoidedBall();
}
}
public class SmallBall extends View {
private final Bitmap sodaCan;
private final static long smallBallPeriod = 60;
private final Handler handler = new Handler();
public SmallBall(Context context) {
super(context);
Paint smallBall = new Paint();
smallBall.setColor(Color.GRAY);
smallBall.setAntiAlias(false);
resetBall();
sodaCan = BitmapFactory.decodeResource(getResources(),R.drawable.sodacan);
Timer movementTimer = new Timer();
movementTimer.scheduleAtFixedRate(smallBallTask, 0, smallBallPeriod);
}
private final TimerTask smallBallTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
invalidate();
if (isBallLanded()){
//Here I want to call on a handleAvoidedBall() in MainActivity
//OR simply have gameView here if possible
// gameView.avoidedBall();
//OR
//SomeMainAcitvityObject.handleAvoidedBall();
}
}
});
}
};
#Override
protected void onDraw(Canvas canvas) {
..... //Do stuff}
}
So as I hopefully have explained somewhat decent now, I'm wondering how to either send gameView into the SmallBall view OR how to call on handleAvoidedBall() in MainActivity from the SmallBall view?
Thank you for your time and hope you have a wonderful day!
Your best option would be to define a listener that you would set on the SmallBallView.
Define the listener:
public interface BallListener {
void onAvoided(SmallBall ball);
}
And then inside your SmallBall class, you would have this method:
public void setListener(BallListener listener){
this.listener = listener;
}
And then call this in your activity, after you've instantiated the SmallBall class:
smallBall.setListener(new SmallBallListener(){
#Override
public void onAvoided(SmallBall ball){
// Do stuff here
}
})
As #LukeWaggoner mentioned, you should consider using listeners instead of making view static in your activity.
You told us, that you'd like to add more than one SmallBall views, so I figure that you don't want to write a listener's code for each of them.
It is easily doable with MainActivity implementing SmallBallListener.
Listener:
public interface SmallBallListener {
void onAvoidedBall();
}
SmallBall class:
public void setListener(SmallBallListener listener){
this.listener = listener;
}
MainActivity:
public class MainActivity extends AppCompatActivity implements SmallBallListener {
private FishView gameView;
private SmallBall smallBall ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
screen.addView(gameView); // first view
// Add 10 small ball views
for(int i = 0; i < 10; i++) {
SmallBall ball = new SmallBall(this);
ball.setListener(this); // MainActivity is a listener here, so each ball has the same listener code
screen.addView(ball);
}
}
//this is the method I want to reach through the View
public void handleAvoidedBall() {
gameView.avoidedBall();
}
#Override
public void onAvoidedBall() { // this is the SmallBallListener method
this.handleAvoidedBall();
}
}
So whichever SmallBall view call listener.onAvoidedBall(), it will fire onAvoidedBall() method in MainActivity class.
Turns out all I had to do was to set:
private FishView gameView;
to:
public static FishView gameView;
And then simply use "MainActivity.gameView" in the SmallBall view. This gave me no additional warings either, so that was good also.
Outline of my code is :
public class MainActivity extends Activity {
Client client;
MyImageView iv;
Bitmap b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyImageView iv = new MyImageView(this);
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.untitled);
iv=(MyImageView)findViewById(R.id.ImageView1);}
iv.setImageBitmap(bMap);
}
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.zooming.MyImageView
android:id="#+id/ImageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:clickable="true"
android:scaleType="matrix" />
</LinearLayout>
MyImgaeView.java
MyImageView extends View {
public MyImageView(Context ct){
super(ct);
//some other works
gestureDetector = new GestureDetector(new MyGestureDetector());
new ConnectTask().execute("");
}
//Other code
class MyGestureDetector extends SimpleOnGestureListener {
#Override
public boolean onDoubleTap(MotionEvent event) {
iv=(MyImageView)findViewById(R.id.ImageView1);
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
iv.setImageBitmap(bMap);
return true;
}
}
class connectTask extends AsyncTask<String,Bitmap,Bitmap>
{
#Override
protected Bitmap doInBackground(String... message) {
//some code to get the bitmap
publishProgress(mybitmap);
return null;
}
#Override
public void onProgressUpdate(Bitmap... values) {
super.onProgressUpdate(values);
iv=(MyImageView)findViewById(R.id.ImageView1);
if(iv==null)
Log.i("Exception",ex.toString());
iv.setImageBitmap(values[0]);
}
}
}
iv is always returning null in ConnectTask(AsynTask) while its working fine in MyGestureDetector...why? also when i am making the ConnectTask the inner class of MainActivity then its working fine...!!
You should use findViewById() only once in the right context. Three ways you could achieve this with your code:
Change Activity to contain your GestureListener and the AsynkTask as inner classes and reference the field iv of your Activity
Keep GestureListener and AsynkTask as standalone classes and add the MyImageView as parameter to their constructor. Construct the two instances for this two classes in onCreate() after the findViewById()
Put GestureListener and AsynkTask as inner classes of MyImageView and add MyImageView as parameter to their constructor. When constructing the two instances from within MyImage just pass this.
findViewById() is context sensitive. This means it searches for a view starting at the current context. If the current context is an Activity it searches thru the corresponding XML Layout. If the context is a view, it just searching from that view downwards. In your case there's a good chance that the findViewById() is searching down the view only for the id - and cant find it. I say 'a good chance' because IMO the one in onDoubleTap() should also not work.
EDIT:
When I created my first custom view, I used the tutorial provided by the Android documentation.
It also has a nice and helpful section about the context.
Please try something like this:
MyImageView extends View {
public MyImageView(Context ct){
super(ct);
//some other works
gestureDetector = new GestureDetector(new MyGestureDetector());
//no it have to be in other place
//new ConnectTask().execute("");
}
//function which set image after task, of course you can in parameter set bitmap, string
//or whatever you want
public void setImageInThread(int id_image){
new ConnectTask().execute(id_image);
}
class connectTask extends AsyncTask<Integer,Void,Bitmap>
{
#Override
protected Bitmap doInBackground(Ingeter... message) {
//some code to get the bitmap
// publishProgress(mybitmap); do you really need this?
//here you can load/decode image
Bitmap bitmapa = BitmapFactory.decodeResource(getResources(), message[0]);
return bitmapa;
}
#Override
protected void onPostExecute(Bitmap toShow) {
if(toShow == null)
return; //is error
MyImageView.this.setImageBitmap(toShow);
}
/*#Override
public void onProgressUpdate(Bitmap... values) {
super.onProgressUpdate(values);
iv=(MyImageView)findViewById(R.id.ImageView1);
if(iv==null)
Log.i("Exception",ex.toString());
iv.setImageBitmap(values[0]);
}*/
}
}
Hi i want create simple apps.i use the one customclass which name like a Drawcanvas which purpose to draw runtime canvas.so i use the ontouchListener and OnClicklistener onthis. but those event can`t working.my code is below.
this the class where i use the Custom class name like DrawCanvas
public class CanvasExample extends Activity
{
/** Called when the activity is first created. */
RelativeLayout relMainOperationLayout;
RelativeLayout relTabHeader;
RelativeLayout relMidalLayout;
RelativeLayout relBelowLayout;
Context myContext;
DrawCanvas drawCanvas;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
myContext=CanvasExample.this;
LayoutInflater layoutInflater=(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int layoutId = myContext.getResources().getIdentifier("main","layout",getPackageName());
relMainOperationLayout = (RelativeLayout) layoutInflater.inflate(layoutId,null);
relTabHeader=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relHeadLayout);
relMidalLayout=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relmidalLayout);
relBelowLayout=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relBelowLayout);
drawCanvas=new DrawCanvas(CanvasExample.this,myContext);
drawCanvas.setBackgroundColor(Color.YELLOW);
RelativeLayout.LayoutParams drawParams=new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,400);
drawParams.addRule(RelativeLayout.BELOW, relTabHeader.getId());
//relMidalLayout.addView(drawCanvas,drawParams);
relMainOperationLayout.addView(drawCanvas,drawParams);
setContentView(relMainOperationLayout);
}
And This is my CustomClass code which extend View. Name DrawCanvas
public class DrawCanvas extends View implements View.OnTouchListener,View.OnClickListener
{
Context drawContext;
Activity drawActivity;
public DrawCanvas(Activity activity,Context context)
{
super(activity);
this.drawActivity=activity;
this.drawContext=context;
}
#Override
public void onClick(View v)
{
System.err.println("Click Here");
Toast.makeText(drawContext, "Click ", 1000).show();
}
#Override
public boolean onTouch(View v, MotionEvent event)
{
System.err.println("Touch Here");
return true;
}
}
i am new in canvas.
You have to use setOnTouchListener and setOnClickListener (though I don't think click events will help you) to register the click and touch events for your View.
public DrawCanvas(Activity activity,Context context) {
super(activity);
this.drawActivity=activity;
this.drawContext=context;
setOnTouchListener(this);
setOnClickListener(this);
}
Here is my program.
public class MathsExplorer extends Activity {
/** Called when the activity is first created. */
private GraphicsView view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(view);
}
}
public class GraphicsView extends View {
public GraphicsView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
String background = "/Maths Explorer/bin/res/drawable/MC900436279.jpg";
Bitmap b = BitmapFactory.decodeFile(background);
canvas.drawBitmap(b, 10, 10, null);
}
}
It quits right away with the error "Unfortunatly, Maths Explorer has stopped."
Can anyone help me? I'm not sure, I'm just trying to display an image.
I think that path to file is wrong, you can't do that.
Try this.
I have searched this issue for hours...
Is it possible to launch google maps navigation within my app and display a textview with some information on it? I have to create an app which passes the destination address to Maps Navigation and while Navigation is working show a textview with the cars model name on the bottom of the app. Is this doable?
Is it possible to launch google maps navigation within my app and display a textview with some information on it?
You cannot embed other applications in yours, and you cannot add your own widgets to some other application's UI.
Try this.
public class FloatingOverNewBooking extends Service {
private WindowManager windowManager;
private FrameLayout frameLayout;
private String str_ride_id;
public static final String BROADCAST_ACTION = "com.yourpackage.YourActivity";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
timerLocation = new Timer();
createFloatingBackButton();
}
Timer timerLocation;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// to receive any data from activity
str_ride_id = intent.getStringExtra("RIDE_ID");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (frameLayout != null) {
//((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(frameLayout);
windowManager.removeView(frameLayout);
frameLayout = null;
}
timerLocation.cancel();
}
private void createFloatingBackButton() {
ClientLocatedActivity.isFloatingIconServiceAlive = true;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY ,
WindowManager.LayoutParams. FLAG_DIM_BEHIND, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
frameLayout = new FrameLayout(this);
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
// Here is the place where you can inject whatever layout you want in the frame layout
layoutInflater.inflate(R.layout.share_new_booking_alert, frameLayout);
final TextView txtName = (TextView) frameLayout.findViewById(R.id.txtName);
Button backOnMap = (Button) frameLayout.findViewById(R.id.dialog_button);
if(!ObjectUtility.isNullOrEmpty(Config.Share.newPassenger)){
txtName.setText(Config.Share.newPassenger.getUsername());
}
backOnMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
am.killBackgroundProcesses("com.google.android.apps.maps");
//MainActivity.getInstance().getShareRideDataById("go");
FloatingOverNewBooking.this.stopSelf();
ClientLocatedActivity.isFloatingIconServiceAlive = false;
} catch (Exception e) {
e.printStackTrace();
}
}
});
windowManager.addView(frameLayout, windowManagerParams);
}
}