I'm developing an android app and using a shared element transition between the splash screen activity and my login activity. while the transition is happening i get to see the background of my phone, apps and everthing, the only thing that i can see from my application is the logo animation, everything else, gone.
Here is my code:
Splash Screen (Origin)
<LinearLayout
android:id="#+id/meofat_logo"
android:layout_width="86dp"
android:layout_height="86dp"
android:layout_gravity="center"
android:background="#drawable/meofat_logo"
android:orientation="vertical"
android:layout_marginTop="210dp"
android:elevation="24dp"
android:transitionName="logo"/>
<LinearLayout
android:id="#+id/meofat_tipo"
android:layout_width="160dp"
android:layout_height="50dp"
android:background="#drawable/meofat_tipo"
android:layout_gravity="center"
android:elevation="24dp"
android:transitionName="tipo"/>
Login Screen (Destination)
<LinearLayout
android:id="#+id/meofat_logo"
android:layout_width="58dp"
android:layout_height="58dp"
android:layout_gravity="center"
android:background="#drawable/meofat_logo"
android:orientation="vertical"
android:layout_marginTop="80dp"
android:elevation="24dp"
android:transitionName="logo"/>
<LinearLayout
android:id="#+id/meofat_tipo"
android:layout_width="106dp"
android:layout_height="33dp"
android:background="#drawable/meofat_tipo"
android:layout_gravity="center"
android:elevation="24dp"
android:transitionName="tipo"/>
SplashScreen Code:
public class RedirectActivity extends Activity {
private static int SPLASH_TIME_OUT = 2000;
LinearLayout logo,tipo;
Animation upToDown;
Animation downToUp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_redirect);
logo = (LinearLayout) findViewById(R.id.meofat_logo);
tipo = (LinearLayout) findViewById(R.id.meofat_tipo);
upToDown = AnimationUtils.loadAnimation(this,R.anim.uptodown);
logo.setAnimation(upToDown);
downToUp = AnimationUtils.loadAnimation(this,R.anim.downtoup);
tipo.setAnimation(downToUp);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
MEOFatSession session = new MEOFatSession(RedirectActivity.this);
if (session.isLoggedIn()){
Intent goToMeasurement = new Intent(RedirectActivity.this,
MeasurementActivity.class);
RetrofitInitializer.getInstance().addCredentials(session.getCredentials());
startActivity(goToMeasurement);
finish();
} else {
Intent goToLogin = new Intent(RedirectActivity.this,
LoginActivity.class);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.
makeSceneTransitionAnimation(RedirectActivity.this,findViewById(R.id.meofat_logo),
"logo");
startActivity(goToLogin, optionsCompat.toBundle());
finish();
}
}
},SPLASH_TIME_OUT);
}
}
A gif trying to illustrate the problem.
https://giphy.com/gifs/d1G6hKgTAsX5hOo0
Removing the finish() method solved the issue. Apparently it would destroy the activity during the animation causing it to vanish.
Like #GaboSampaio said, finish() caused the flickering. You can delay it :
Handler handler = new Handler();
handler.postDelayed(this::finish, 1000);
Intent goToLogin = new Intent(RedirectActivity.this, LoginActivity.class);
ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
RedirectActivity.this,
// Now we provide a list of Pair items which contain the view we can transitioning
// from, and the name of the view it is transitioning to, in the launched activity
new Pair<View, String>(findViewById(R.id.logo_splash),
"tipo"));
ActivityCompat.startActivity(RedirectActivity.this, intent, activityOptions.toBundle());
Related
Im developing a contacts app, and for now Ive been trying to get this drawables from the array get uploaded into the Gridview on the main screen AFTER the save mosaic button is clicked in the mosaic creation screen.
the floating action button (red plus button) on the mosaicListScreen (main screen) leads to the MosaicCreationScreen). the user hypothetically uploads the image and enters the mosaic name then saves using the save mosaic button, as can be seen in the image here
For now, before I focus on uploading image and letting the user create their own unique mosaics (groups), Im testing the Gridview updating with some drawables, which are listed in the array as can be seen in the code below.
The issue thats occuring is as soon as the user clicks the floating action button on the main screen, it updates the gridview with the drawables listed in the array of the MosaicCreation Screen, THEN it goes to the MosaicCreationScreen, and when save mosaic button is clicked on the MosaicCreationScreen, the intent goes to the main screen as its supposed to do, except the gridview will have nothing on it.
so its like its doing the opposite of whats supposed to happen in steps.
here is my code for the two screens:
public class mosaicsListScreen extends AppCompatActivity {
public static mosaicsListScreen theScreen; //this variable is used in the MosaicCreationScreen to point to this screen to find the GridView by id
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
theScreen = this;
setContentView(R.layout.activity_mosaics_list_screen);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.createMosaicButton);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),MosaicCreationScreen.class);
startActivity(intent);
finish();
}
});
}
}
here is the code for the MosaicCreationScreen (the one that opens after user clicks floating action button from mosaicListScreen (main screen))
public class MosaicCreationScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mosaic_creation_screen);
final GridView mosaicList = (GridView) mosaicsListScreen.theScreen.findViewById(R.id.mosaicList);
mosaicList.setAdapter(new ImageAdapter(this)); //this line of code displays the mosaics on mosaicListScreen
Button saveNewMosaicButton = (Button) findViewById(R.id.saveNewMosaicButton);
saveNewMosaicButton.setOnClickListener(new AdapterView.OnClickListener() {
#Override
public void onClick(View view) {
//mThumbIds.notify();
Intent intent = new Intent(getApplicationContext(), mosaicsListScreen.class);
startActivity(intent);
finish();
//mosaicList.setAdapter(new ImageAdapter(this)); //this displays the mosaics on mosaicListScreen, it logically should go here, however "this" causes an error saying ImageAdapter (android.content.Context) in ImageAdapter cannot be applied to (anonymous android.view.View.OnClickListener)
Toast.makeText(mosaicsListScreen.theScreen, "Mosaic Created!", Toast.LENGTH_SHORT).show();
}
});
/* mosaicList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(mosaicsListScreen.theScreen, "", Toast.LENGTH_SHORT).show();
}
});*/
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
//this array holds the drawables that would appear on the Gridview
private Integer[] mThumbIds = {
R.drawable.family,
R.drawable.project
};
}
}
Here are the XML for the layouts:
content_mosaics_list_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="codesages.mosaic.mosaicsListScreen"
tools:showIn="#layout/activity_mosaics_list_screen">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/create_a_mosaic_or_pick_from_the_mosaics_created"
android:id="#+id/textView4"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="20sp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/deleteMosaicButton"
android:src="#android:drawable/ic_menu_delete"
android:clickable="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:contentDescription="" />
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/textView4"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="14dp"
android:id="#+id/mosaicList"
android:layout_above="#+id/textView7"
android:numColumns="auto_fit" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="#string/holdMosaictoDeleteLabel"
android:id="#+id/textView7"
android:layout_marginBottom="16dp"
android:layout_above="#+id/deleteMosaicButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
activity_mosaics_list_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context="codesages.mosaic.mosaicsListScreen">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/createMosaicButton"
android:layout_width="56dp"
android:layout_height="66dp"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_input_add" />
<include layout="#layout/content_mosaics_list_screen" />
</android.support.design.widget.CoordinatorLayout>
activity_mosaic_creation_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<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="codesages.mosaic.MosaicCreationScreen"
android:focusable="true">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/mosaicNametextField"
android:hint="Mosaic Name"
android:layout_marginTop="81dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save New Mosaic"
android:id="#+id/saveNewMosaicButton"
android:layout_marginTop="48dp"
android:layout_below="#+id/uploadMosaicImageButton"
android:layout_centerHorizontal="true"
android:enabled="true"
android:clickable="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Upload Mosaic Image"
android:id="#+id/uploadMosaicImageButton"
android:layout_marginTop="68dp"
android:layout_below="#+id/mosaicNametextField"
android:layout_centerHorizontal="true"
android:enabled="true"
android:clickable="true" />
</RelativeLayout>
mosaicList.setAdapter(new ImageAdapter(this));
thats what appears to be creating the mosaics. if i comment this out, i wont see anything in the gridview.
however, i believe that should be inside the saveNewMosaicButton onClick, but I am getting an error that says "saying ImageAdapter (android.content.Context) in ImageAdapter cannot be applied to (anonymous android.view.View.OnClickListener)"
HERE is an image example of what the desired result should be. however whats happening right now is as ive stated, as soon as the floating action button is clicked, the mosaics are created, THEN it takes you to the creation screen, in which wehn i click save mosaics, it actually erases the mosaics...a job of the trash icon which is too soon to function for now heh.
appreciate help on this
Currently, you have
public static mosaicsListScreen theScreen;
in your first Activity which you use to fill the ListView in this first Activity. This is a dangerous approach because the Activity instance referenced by this variable may be destroyed, for example if you're doing work in your second Activity (e.g. downloading images) which uses much memory, but also if the user somehow triggers a configuration change.
As you are calling finish() after starting the second Activity, you even tell the system that the first Activity may be destroyed. The only reason you did not get a NPE is that the system destroys the finished Activity not instantly but as soon as it seems a good idea to do so.
All in all, you need a way to safely transmit information from one Activity to the other. In your case, I think you would like to send the Uri of the selected images ( or for now, send the resource id of the selected drawables). Both can be accomplished by using Intent extras.
Basically, there are two options:
use startActivityForResult() and override onActivityResult() to obtain the desired information for the first Activity
simply start the first Activity from the second Activity once you have the result and use getIntent() in the first Activity (e.g. in onCreate()) to check for results
No matter what you do, always access UI elements like the ListView in the Activity to which they belong!
If you choose the second option, your first Activity could look like this:
public class mosaicsListScreen extends AppCompatActivity {
public static final String THUMB_IDS = "someuniquestring";
private GridView mosaicList;
private ArrayList<Integer> mThumbIds;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mosaics_list_screen);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.createMosaicButton);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),MosaicCreationScreen.class);
startActivity(intent);
finish();
}
});
fillThumbIds();
mosaicList = (GridView) findViewById(R.id.mosaicList);
// Note: Adapter code in this Activity
mosaicList.setAdapter(new ImageAdapter(this));
}
private void fillThumbIds()
{
mThumbIds = new ArrayList();
// somehow get older thumb ids if necessary (from database?)
// and add to ArrayList like this:
mThumbIds.add(R.drawable.family);
mThumbIds.add(R.drawable.project);
// assuming we transmit resource id's: use an int array with the Intent
int[] newThumbIds = getIntent().getIntArrayExtra(THUMB_IDS);
if (newThumbIds != null)
{
// loop through the array to add new thumb ids
for (int i = 0; i < newThumbIds.length; i++) {
mThumbIds.add(newThumbIds[i]);
}
}
}
// Adapter code goes here
// Note: thumbIds no longer as array but as ArrayList!
}
In the second Activity, you put the selected thumb ids as Intent extra as follows:
saveNewMosaicButton.setOnClickListener(new AdapterView.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), mosaicsListScreen.class);
// if 'myNewThumbs' is the int array with the new thumb ids
intent.putExtra(mosaicsListScreen.THUMB_IDS, myNewThumbs);
startActivity(intent);
finish();
}
});
I want to create a shared transition for my app, but it doesn't work like it should. It should make that fancy animation before the next activity appears, but it only opens it. And the image doesn't show there too. I have this code:
public void loadContent(final List<Post> posts){
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
ListAdapter adapter = new ListAdapter(posts, new View.OnClickListener(){
#Override
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, PostViewActivity.class);
ImageView placeImage = (ImageView)v.findViewById(R.id.postPhoto);
TextView textView = (TextView)v.findViewById(R.id.textText);
Pair<View, String> imagePair = Pair.create((View) placeImage, getString(R.string.transition_image));
Pair<View, String> holderPair = Pair.create((View) textView, getString(R.string.transition_username));
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, imagePair, holderPair);
//ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, holderPair);
ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle());
}
});
RecyclerView rv = (RecyclerView)findViewById(R.id.post_list);
StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
rv.setLayoutManager(lm);
rv.setAdapter(adapter);
}
});
And these two XML files:
id:orientation="vertical"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:paddingTop="0px"
android:id="#+id/postPhoto"
android:transitionName="#string/transition_image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorAccent"
android:id="#+id/usernameText"
android:transitionName="#string/transition_username"/>
And the other XML file:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="#string/transition_image"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="#string/transition_username"/>
It only opens the new activity, but not with the Image and the text. I tried it also only with the image. What's wrong?
I created a Layout and a Activity to that Layout.
In the Layout I only have an ImageView with a png image that is located in the Resources/Drawables.
When I launch the Application in my Device the ImageView doesn´t appear on the screen.
This is my XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px"
android:gravity="center"
android:visibility="visible"
tools:visibility="visible">
<ImageView
android:layout_width="350.0dp"
android:layout_height="279.5dp"
android:id="#+id/OpeningLogo"
android:layout_gravity="center"
android:visibility="visible"
tools:visibility="visible"
android:src="#drawable/logo"
android:adjustViewBounds="true" />
</LinearLayout>
This is the Activity Code:
namespace *********
{
[Activity(Label = "xxxxxxxxx", MainLauncher = true, Icon = "#drawable/Logo")]
public class OpeningActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Opening);
Intent GoToLogin = new Intent(this, typeof(MainActivity));
Thread.Sleep(5000);
this.Finish();
StartActivity(GoToLogin);
}
}
}
If you want me to put something more tell me.
Thanks in advance!
Problem is that you are blocking the UI thread of that Activity and it is never actually shown as intended. The UI thread does not get time to actually draw anything on the screen.
Instead you should do something like:
namespace GridSocios
{
[Activity(Label = "xxxxxxxxx", MainLauncher = true, Icon = "#drawable/Logo", NoHistory = true)]
public class OpeningActivity : Activity
{
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Opening);
await Task.Delay(5000);
var intent = new Intent(this, typeof(MainActivity));
StartActivity(intent);
}
}
}
Also notice the NoHistory = true flag is set. This means that you can't navigate back to this Activity after you have navigated away from it.
I've tried to make an animation from a Floating Action Button to a new activity like said in this page :
http://android-developers.blogspot.be/2014/10/implementing-material-design-in-your.html
In section: Activity + Fragment Transitions
But I don't see any transition on screen.
What is the problem???
In Original Activity:
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:src="#drawable/ic_add_white_48dp"
app:backgroundTint="#color/spg_rosa"
android:transitionName="#string/transition_add_pdv"
app:borderWidth="0dp"
app:elevation="8dp"
app:fabSize="normal" />
In destination Activity, in mainLayout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/spg_azul"
android:gravity="center_horizontal"
android:transitionName="#string/transition_add_pdv"
android:orientation="vertical">
And the code:
fab = (FloatingActionButton) v.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// I added parameters to Intent() because it was giving me error
Intent intent = new Intent(getActivity(), AddActivity.class);
String transitionName = getString(R.string.transition_add_pdv);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(),
fab, // The view which starts the transition
transitionName // The transitionName of the view we’re transitioning to
);
ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
}
});
Any Idea?
To be able to use (Activity activity, View sharedElement, String sharedElementName) you must enable the content transitions feature.
This requires FEATURE_CONTENT_TRANSITIONS to be enabled on the calling
Activity to cause an exit transition. The same must be in the called
Activity to get an entering transition.
To do this, set the feature before the setContentView(int) in the onCreate of both the exiting and entering Activities:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_main);
...
}
Note: This feature is for API 21+. Although, there are some work arounds libraries I believe e.g. github.com/andkulikov/transitions-everywhere
i have the following code and it works great for android 4.4 KitKat.
In the other android version the animation #anim/loading_animation is showing but not moving.
Someone can help me?? Thank you so much!!
public class SplashScreen extends Activity {
// Splash screen timer
private static int SPLASH_TIME_OUT = 4000;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Start your app main activity
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
// close this activity
finish();
}
}, SPLASH_TIME_OUT);
}
}
splash_screen.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/Black" >
<ImageView
android:id="#+id/logo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:contentDescription="#string/image"
android:paddingBottom="20dp"
android:paddingTop="20dp"
android:src="#anim/loading_animation" />
</RelativeLayout>
Just check your manifest file and minimum SK version. Change it to API 8.I hope it works.
If you still face any issue. let me know