Get shared element transitions inside the recylerView - android

I need a shared transition in recylerview to an activity but getting the error "Application cannot be cast to Activity" tried passing Adpater.this/this/Adapter.class but nothing is working
ViewCompat.setTransitionName(holder.imageView, photo.getId());
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, Fullscreen.class);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation((MainActivity) mContext, holder.imageView, ViewCompat.getTransitionName(holder.imageView));
mContext.startActivity(intent, options.toBundle());
}
});
}

problem is in (MainActivity)mContext line. Your mContext is Application type but you try to cast it to Activity type, thats why it throws ClassCastException. Declare your field as Activity mContext; instead of Context mContext; and IDE will show you that you init your mContext variable with wrong type object.

Related

MainActivity is not an enclosing class, "this" makes a constructor error

I'm new to android studio and i have a problem when I'm trying to jump to a new activity, so when the line is:
public class signup_activity extends AppCompatActivity {
ImageButton logupButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup_activity);
logupButton = findViewById(R.id.signuparrow);
logupButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, signup_activity.class);
startActivity(intent);
}
});
}}
I get the error:
'com.example.myapplication.MainActivity' is not an enclosing class
and i so a couple of of people advising to chane the intent to this instead of MainActivity.this
but when im changing to this i get the error:
Cannot resolve constructor 'intent'
Intent intent = new Intent(MainActivity.this, signup_activity.class);
Several things:
First, the first param of Intent() constructor is a context. Since you are on signup_activity you need to do signup_activity.this to use it as a context.
I'd assume you want to go to MainActivity, so your second param should be MainActivity.class. It seems you got the order altered there.
you are in signup_activity and when use Intent in fisrt part you should call the current contex to jump to other activity.
so you should replace
Intent intent = new Intent(signup_activity.this, MainActivity.class);
if you want to jump to signup_activity you can call intent from MainActivity.

Calling startActivity() outside of an Activity context requires FLAG_ACTIVITY_NEW_TASK

I am getting the error AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. The full stack trace:
main Process: com.kd.book, PID: 3487 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? at android.app.ContextImpl.startActivity(ContextImpl.java:1238) at android.app.ContextImpl.startActivity(ContextImpl.java:1225) at com.kd.book.Adapter.MyComicAdapter$1.onClick(MyComicAdapter.java:63) at com.kd.book.Adapter.MyComicAdapter$MyViewHolder.onClick(MyComicAdapter.java:99)
I am new to Android development and do not know how to solve it.
My Code:
public class MyComicAdapter extends RecyclerView.Adapter<MyComicAdapter.MyViewHolder> {
Context context;
List<Comic> comicList;
LayoutInflater inflater;
public MyComicAdapter(Context context, List<Comic> comicList) {
this.context = context;
this.comicList = comicList;
inflater=LayoutInflater.from(context);
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = inflater.inflate(R.layout.comic_item, viewGroup, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
Picasso.get().load(comicList.get(i).Image).into(myViewHolder.comic_image);
myViewHolder.comic_name.setText(comicList.get(i).Name);
//Event
myViewHolder.setRecyclerItemClickListener(new IRecyclerItemClickListener(){
#Override
public void onClick(View view, int position) {
//save the comic selected
Common.comicSelected = comicList.get(position);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(new Intent(context,ChapterActivity.class));
}
});
}
#Override
public int getItemCount() {
return comicList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView comic_name;
ImageView comic_image;
IRecyclerItemClickListener recyclerItemClickListener;
public void setRecyclerItemClickListener(IRecyclerItemClickListener recyclerItemClickListener) {
this.recyclerItemClickListener = recyclerItemClickListener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
comic_image = itemView.findViewById(R.id.image_comic);
comic_name = itemView.findViewById(R.id.comic_name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
recyclerItemClickListener.onClick(view, getAdapterPosition());
}
}
}
Any ideas?
The problem is that you are doing "new Intent" twice:
Once here: Intent intent = new Intent(Intent.ACTION_VIEW);
Second time here: context.startActivity(new Intent(context,ChapterActivity.class))
FLAG_ACTIVITY_NEW_TASK is not set when the activity is started. The corrected version where the Intent is only created once looks like:
Intent intent = new Intent(context, ChapterActivity.class))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
But your real problem is that you need to call startActivity on the Activity context.
getActivity().startActivity(new Intent(getActivity(), ChapterActivity.class));
More discussion here:
How do I start an activity from within a Fragment?
What you were attempting to do with FLAG_ACTIVITY_NEW_TASK should be reserved for rare cases like when you need to launch an Activity from a Service. But it is not necessary or desirable to set that flag when starting an Activity from within a UI context.
This is why the warnings asks:
Is this really what you want?
Setting specialised flags when launching the Activity often leads to unwanted backstack/navigation behaviours.
Also, I cannot see if your adapter is located inside an Activity or Fragment. [You can use "this" inside an Acitivity and getActivity() inside a Fragment]
Lastly, I cannot how you are creating the Adapter, but the way your code is currently organised you need to pass the Activity context into the Adapter for it to work. From a Fragment:
adapter = new MyComicAdapter(getActivity(), list);
From an Activity:
adapter = new MyComicAdapter(this, list);
This will most likely prevent the exception that you are getting.
Try this way,
1. create an interface in your adapter and pass the position to it (hope you know how to make and use an interface).
2. implement that interface to your activity class.
3. in its override method, you will get the position of a list.
4. by using that position, get the required data and call intent in it.
Done.
Change your call to the new activity as follows,
Intent intent=new Intent(context, ChapterActivity.class);
Activity activity=(Activity) context;
activity.startActivity(intent);

how to use intent caller on button click properly?

actually I am bit confused on some thing which is working in one scenario very well but in other scenario that is not working fine so I am here to explain my problem to identify the wrong move made by me, if any on will identify the problem please mention it. thank you.
working fine:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.distance_demo_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ListViewClass.class);
intent.putExtra(ListViewClass.EXTRAS_TARGET_ACTIVITY, Distance.class.getName());
startActivity(intent);
}
});
NOt working fine:
scan = (Button) view.findViewById(R.id.scan);
scan.setOnClickListener(startListener);
}
//Create an anonymous implementation of OnClickListener
private OnClickListener startListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(view.getContext(),"Scanning", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this, ListViewClass.class);
intent.putExtra(ListViewClass.EXTRAS_TARGET_ACTIVITY, Distance.class.getName());
startActivity(intent);
}
}
now the problem is in this line
Intent intent = new Intent(MainActivity.this, ListViewClass.class);
when I use this line in this scenario it shows me error on this line:
Error: 'The constructor Intent(MainActivity, Class<ListViewClass>) is undefined' please mention my problem if you are well aware of it.
use a global context variable glaboaly and use it.
Context myContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myContext = MyActivity.this;
}
and use myContext insted of MainActivity.this.
Im not sure whether it solve the problem, just try it out
When your calling Intent intent = new Intent(MainActivity.this, ListViewClass.class); inside MainActivity class. It will work fine. But when your not in Context of MainActivity class. i.e move to other class. This error will occur.
If you want to rectify, You can follow #jithu method. Otherwise store the context in Application class. And use it in anywhere.
In the first case you are overriding the method onClick().
If you override the method it's like you are declaring the function in your activity class.
This is the reason that you can call MainActivity.this
In the second case you are implementing the abstract method onClick(). You can't call MainActivity.this because your "MainActivity.this" is referencing to the current context and this isn't accessible from OnClickListener.class.

overridePendingTransition on gridview adapter

How can I insert overridePendingTransition on a GridView `Adapter? In this way don't work, without transition startactivity work perfectly
bt.setOnLongClickListener(new OnLongClickListener(){
#Override
public boolean onLongClick(View v) {
final String selectedPad = Drum.pads[position];
Intent modPad = new Intent(v.getContext(), ModifyPad.class);
modPad.putExtra("pad", selectedPad);
context.startActivity(modPad);
overridePendingTransition(R.anim.exit_slid_in, R.anim.exit_slid_out);
return false;
}
});
I've read this post:
android start Activity in adapter (transition animiation direction problem), and comments related, but I don't know how pass the Activity in the Adapter. Any help?
Context is the Base Object of Activity ( see: What is the difference between Activity and Context? ),
so I used following:
Activity activity = (Activity) mContext;
activity.startActivity(repinIntent);
activity.overridePendingTransition(R.anim.act_start_in_from_right, R.anim.act_start_out_to_left);
Refers to: Getting activity from context in android

AndroidRuntimeException "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag"

I create multiple layouts inside a listview, but when i click i get a AndroidRuntimeException "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?"
Im adding
Intent.FLAG_ACTIVITY_NEW_TASK
to my intent but i get the same message! =(
#Override
public View getView(int position, View convertView, ViewGroup parent) {
retval=LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout_anuncio, null);
ImageView image=(ImageView) retval.findViewById(R.id.imageAD);
LoadAds loadAds= new CargaAnuncios();
clickUrl = LoadAds.cargaImagenAnuncio(image, mContext, GlobalInfo.ANUNCIO_CARRIL_PORTADA);
image.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
Bundle bundle=new Bundle();
bundle.putString("url", clickUrl);
Intent intent =new Intent(mContext,CustomWebView.class);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
});
return retval;
}
Replace getApplicationContext() with this. Most likely, you should do that everywhere in your code that you have getApplicationContext() -- only use getApplicationContext() when you specifically need the Application object.
Old thread, but thought this easy solution might help someone. Instead of passing context around, just get it from view. For eg: view.getContext()
#Override
public void onClick(View view) {
Bundle bundle=new Bundle();
bundle.putString("url", clickUrl);
Intent intent =new Intent(view.getContext(),CustomWebView.class);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(intent);
}
I have added:
parent.getApplicationContext()
Instead of just:
getApplicationContext()
Whole line is:
retval=LayoutInflater.from(parent.getApplicationContext()).inflate(R.layout.layout_anuncio, null);
The solution of Warren Lankie Van Tonder is almost the good:
-You should avoid using Activity context and choose Application Context instead, in purpose to prevent memory leaks. This blog of an Android developer explains that http://android-developers.blogspot.be/2009/01/avoiding-memory-leaks.html
-But in the case of Activity context is the only solution for your code (maybe for calling another activity from outside an activity) and regarding the link above, you have to release the static reference in each onPause() with
AppGlobals.setAppContext(null);
In return, set the static field in onResume and not onCreate.
Thanks to CommonsWare i came up with this solution which worked best.
I added a new class
package com.test.test;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class AppGlobals extends Activity {
private static Context appContext;
public static Context getAppContext(){
return appContext;
}
public static void setAppContext(Context context){
appContext = context;
}
public static void StartActivity(Intent intent){
appContext.startActivity(intent);
}
}
All i needed to do then was add the below code on each activity onCreate that i navigated to.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
AppGlobals.setAppContext(this);
}
This allowed the new intent to start as if it working with normal application flow and this way i didn't have to set a Flag for the intent.
Calling the start activity method is as easy as:
Intent totalTimerIntent = new Intent(AppGlobals.getAppContext(), TotalTimer.class);
AppGlobals.StartActivity(totalTimerIntent);
Hope this helps someone as it has helped me.
Thank you CommonsWare.
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);
or
Context mContext = getAppliactionContext();
CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist);
change to below
CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

Categories

Resources