I'm constantly receiving data in MainActivity and I need it to only be written a textView when the fragment that contains the textView is inflated. Obviously the app crashes if I try to write to a textView that is in a fragment currently not in display. I have made a dummy activity to explain my problem and I'm using a countdown timer to represent the data that is continually changing in the MainActivity. The issue resides in MainActivity.
Would someone mind explaining how I can only write to the textView when it is inflated?
Thanks
FragmentA.java (Fragment B and C are almost identical)
package com.felhr.scrolltabs;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Luke on 20/04/2015.
*/
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_a, container, false);
}
}
MainActivity.java
package com.felhr.scrolltabs;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
ViewPager viewPager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager)findViewById(R.id.pager);
FragmentManager fragmentManager = getSupportFragmentManager();
viewPager.setAdapter(new MyAdapter(fragmentManager));
final TextView timer = (TextView)findViewById(R.id.textViewTimer);
// Countdown timer code -> to be run constantly but only displayed in Fragment A is in focus
// This section breaks the code
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("done!");
}
}.start();
}
}
class MyAdapter extends FragmentPagerAdapter
{
public MyAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
Log.d("SWIPE","get Item is called"+i);
if (i==0)
{
fragment=new FragmentA();
}
if (i==1)
{
fragment=new FragmentB();
}
if (i==2)
{
fragment=new FragmentC();
}
return fragment;
}
#Override
public int getCount() {
Log.d("SWIPE","get count is called");
return 3;
}
// talks to title to give the page
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) {
return "Tab 1";
}
if (position == 1) {
return "Tab 2";
}
if (position == 2) {
return "Tab 3";
}
return null;
}
}
fragment_a.xml (fragments b and c are almost identical)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C3f3f3">
<TextView
android:id="#+id/textViewTimer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment A"
android:textColor="#000000"
android:gravity="center"/>
</RelativeLayout>
activity_main.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/pager">
<android.support.v4.view.PagerTitleStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/title"
android:background="#33B5E5">
</android.support.v4.view.PagerTitleStrip>
</android.support.v4.view.ViewPager>
Related
I have researched a lot on SharedElement Transitions , however I could only find Transitions for onclick event.
I want the animation between Fragments where the speed of animation is controlled by the user's scrolling speed. If the user stops in between while scrolling the objects should be still.
Example :
In this image , the viewpager is in the middle of screen1 and screen2 and the animating objects are in stopped state.
These objects move from one screen to another and also change their positions.
The translation animations part I have figured out but how to achieve this shared element transition with viewpager between fragments. And moreover it should scroll/animate with the speed of finger swipe.
MainActivity.java
package com.karan.onboardanimation;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private MyFragmentPagerAdapter pagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: ");
ViewPager pager = (ViewPager) findViewById(R.id.pager);
FragmentManager fm = getSupportFragmentManager();
pagerAdapter = new MyFragmentPagerAdapter(fm);
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(0);
}
}
FirstFragment.java- This fragment has an imageview which has to shared with second fragment when user is swiping on the viewpager.
package com.karan.onboardanimation;
import android.app.ActivityOptions;
import android.os.Build;
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.ImageView;
public class FirstFragment extends Fragment {
private static final String TAG = "FirstFragment";
ImageView imageView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 21){
}
Log.d(TAG, "onCreate: ");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: ");
View view = inflater.inflate(R.layout.first_fragment, container, false);
imageView = (ImageView) view.findViewById(R.id.img1);
ViewPagerTransformer viewPagerTransformer = new ViewPagerTransformer();
viewPagerTransformer.transformPage(imageView, 1);
return view;
}
}
MyFragmentPagerAdapter.java
package com.karan.onboardanimation;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.Log;
class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private static final String TAG = "MyFragmentPagerAdapter";
final int PAGE_COUNT = 2;
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
Log.d(TAG, "MyFragmentPagerAdapter: ");
}
#Override
public Fragment getItem(int position) {
Log.d(TAG, "getItem: ");
switch (position) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
default:
return null;
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
second_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d02030"
android:orientation="vertical">
<ImageView
android:id="#+id/img2"
android:layout_width="100dp"
android:layout_centerInParent="true"
android:src="#drawable/orange_centre"
android:transitionName="selectedIcon"
android:layout_height="100dp" />
</RelativeLayout>
first_fragment.xml
<?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:orientation="vertical">
<ImageView
android:id="#+id/img1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="#drawable/orange_centre" />
</LinearLayout>
Edit1-
This question is not a duplicate of link mentioned in comment because that question is a sub part of my question. The difference is that the animation in that question happens on a click with a static speed. However in my question, the speed of animation must be equal to the speed of ViewPager swipe speed.
You can try PageTransformer. It is not shared transition but more of view animation that is dependent on page position offset generated by swipe events.
I have been developing an app which contain navigation drawer on main page and on main page I have an framelayout in which I am displaying HomeFragment.java which contain viewPager.
The problem is when I launch my application the HomeFragment.java gets called and viewpager works fine. But when I click Home but in navigation drawer which call HomeFragment.java then the view pager gets invisible. Here are my code.
Please Help.
MainActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.motomojoapp.R;
import com.motomojoapp.fragment.FragmentDrawer;
public class MainActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {
Toolbar toolbar;
TextView textView;
private FragmentDrawer drawerFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar_white);
setToolbar();
drawerFragment = (FragmentDrawer)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), toolbar);
drawerFragment.setDrawerListener(this);
FragmentManager fragmentManager = this.getSupportFragmentManager();
Fragment fragment = new HomeFragment(fragmentManager);
if (fragment != null) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle("");
}
}
public void setToolbar() {
toolbar.setTitle("");
textView = (TextView) findViewById(R.id.toolbar_title_white);
textView.setText(getResources().getString(R.string.home));
toolbar.setTitleTextColor(getResources().getColor(R.color.colorPrimary));
setSupportActionBar(toolbar);
}
#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, 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();
if (id == R.id.notification) {
startActivity(new Intent(this, NotificationActivity.class));
return true;
}else if (id == R.id.map) {
startActivity(new Intent(this, MapActivity.class));
return true;
}
//noinspection SimplifiableIfStatement
return super.onOptionsItemSelected(item);
}
#Override
public void onDrawerItemSelected(View view, int position) {
displayView(position);
}
private void displayView(int position) {
switch (position) {
case 0:
FragmentManager fragmentManager = this.getSupportFragmentManager();
Fragment fragment = new HomeFragment(fragmentManager);
if (fragment != null) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle("");
}
break;
case 1:
case 2:
break;
default:
FragmentManager fragmentManager1 = this.getSupportFragmentManager();
Fragment fragment1 = new HomeFragment(fragmentManager1);
if (fragment1 != null) {
FragmentTransaction fragmentTransaction = fragmentManager1.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment1);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle("");
}
break;
}
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="#+id/toolbar_white"
layout="#layout/toolbar_white" />
</LinearLayout>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_body"
android:layout_marginTop="6dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
<fragment
android:id="#+id/fragment_navigation_drawer"
android:name="com.motomojoapp.fragment.FragmentDrawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/fragment_navigation_drawer"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
HomeFragment.java
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.motomojoapp.R;
import com.motomojoapp.customadapter.SlideAdapter;
public class HomeFragment extends Fragment {
private SlideAdapter adapter;
private ViewPager viewPager;
FragmentManager fragmentManager ;
public HomeFragment(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
public HomeFragment() {
// Required empty public constructor11
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
viewPager.setClipToPadding(false);
viewPager.setPageMargin(35);
adapter = new SlideAdapter(fragmentManager);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(adapter.FIRST_PAGE);
// Inflate the layout for this fragment
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
fragment_home.xml
<LinearLayout 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:orientation="vertical">
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginTop="6dp"
android:paddingLeft="34dp"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:paddingRight="12dp" />
</LinearLayout>
SlideAdapter.java
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.motomojoapp.fragment.SlideFragment;
public class SlideAdapter extends FragmentPagerAdapter {
private int PAGES = 3;
// You can choose a bigger number for LOOPS, but you know, nobody will fling
// more than 1000 times just in order to test your "infinite" ViewPager :D
private int LOOPS = 1000;
public int FIRST_PAGE = PAGES * LOOPS / 2;
public SlideAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
position = position % PAGES;
return SlideFragment.newInstance(Integer.toString(position + 1));
}
#Override
public int getCount() {
return PAGES * LOOPS;
}
#Override
public float getPageWidth(int position) {
return 0.93f;
}
}
SlideFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.motomojoapp.R;
public class SlideFragment extends Fragment {
private static final String ARG_PAGE_NUMBER = "pageNumber";
private String mParam;
private TextView tvPos;
public SlideFragment() {
// Required empty public constructor
}
public static SlideFragment newInstance(String pageNumber) {
Bundle args = new Bundle();
args.putString(ARG_PAGE_NUMBER, pageNumber);
SlideFragment fragment = new SlideFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam = getArguments().getString(ARG_PAGE_NUMBER);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
FrameLayout root = (FrameLayout) inflater.inflate(R.layout.fragment_slide, container, false);
tvPos = (TextView) root.findViewById(R.id.text);
tvPos.setText("Page " + mParam);
return root;
}
}
I created a Tabbed Activaity using Android Studio 1.2.2 wizard, I hope to close this window when I click the button btnClose, I write the code rootView.getContext().finish(); , but it's wrong,
and PlaceholderFragmentOld.this.finish(); is wrong too.
How can I do? Thanks!
PlaceholderFragmentOld.java
package ui.tab;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.Fragment;
import android.widget.Button;
import com.google.android.gms.ads.AdView;
import info.dodata.messagecleanup.R;
import bll.PublicParFun;
import info.dodata.messagecleanup.R;
public class PlaceholderFragmentOld extends Fragment {
private AdView adView;
public PlaceholderFragmentOld() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.cleanup_delete_fragment_old, container, false);
adView=(AdView) rootView.findViewById(R.id.adView);
PublicParFun.SetAD(adView);
SetButtons(rootView);
return rootView;
}
private void SetButtons(final View rootView){
rootView.findViewById(R.id.btnClose).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rootView.getContext().finish();
}
});
}
}
CleanupDelete.java
package ui;
import java.util.Locale;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.FragmentPagerAdapter;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import info.dodata.messagecleanup.R;
import ui.tab.PlaceholderFragmentOld;
import ui.tab.PlaceholderFragmentPerson;
import ui.tab.PlaceholderFragmentReduce;
import ui.tab.PlaceholderFragmentTrim;
public class CleanupDelete extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cleanup_delete);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment;
switch(position){
case 0:
fragment = new PlaceholderFragmentOld();
break;
case 1:
fragment = new PlaceholderFragmentReduce();
break;
case 2:
fragment = new PlaceholderFragmentTrim();
break;
case 3:
fragment = new PlaceholderFragmentPerson();
break;
default:
throw new IllegalArgumentException("Invalid section number");
}
return fragment;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.Tab_Old);
case 1:
return getString(R.string.Tab_Reduce);
case 2:
return getString(R.string.Tab_Trim);
case 3:
return getString(R.string.Tab_Person);
}
return null;
}
}
}
cleanup_delete.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/pager"
android:layout_width="match_parent" android:layout_height="match_parent"
/>
cleanup_delete_fragment_old.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:background="#drawable/border_ui" >
<LinearLayout
android:id="#+id/linearLayoutMain"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:paddingTop="20dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:orientation="vertical" >
<TextView
android:id="#+id/tVDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dip"
style="#style/myTextDesciption"
android:text="This is a descript"/>
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayoutToolBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:weightSum="4" >
<Button
android:id="#+id/btnDelete"
style="#style/myTextMedium"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:text="#string/BtnDelete" />
<Button
android:id="#+id/btnClose"
style="#style/myTextMedium"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:text="#string/BtnClose" />
</LinearLayout>
</RelativeLayout>
finish() can only be called in an Activity. Given that, you do it this way:
// Somewhere in your fragment
private void finishActivity() {
if(getActivity() != null) {
getActivity().finish();
}
}
And you could then call that method to finish your Activity:
// Somewhere in your click listener
finishActivity();
IMPORTANT: There is a possibility for getActivity() to return null. This is especially dangerous when the fragment is being detached from your Activity (when using a ViewPager or when you're juggling between numerous fragments in an activity). Calling it without checking will pose your code to the threat of NullPointerException.
You may do something like this.
#Override
public void onClick(View v) {
getActivity().finish();
}
You should use getActivity().finish();
In order to move from a fragment to activity using Kotlin, add the code below:
if(activity != null) {
activity?.finish()
}
I have created a fragment activity with 3 tabs. When I move from tab 1 to tab 3, it takes around 5 seconds to load tab 3( due to some time consuming task ). During this loading time, I want to show a dialog.
I put the dialog inside onTabSelected(), but the dialog shows up only after the 3rd tab display comes up. I want it to show between "the time I clicked the 3rd tab" and "the time the 3rd tab actually comes up". Please do let me know ur suggestions.
Editted :
Sample code :
MainActivity.java:
package com.example.trial;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Window;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private static final String STATE_SELECTED_NAVIGATION_ITEM ="selected_navigation_item";
ProgressDialog nDialog;
Fragment dashboardFrag = new DashboardTab();
Fragment Tab1 = new Tab1();
Fragment Tab2 = new Tab2();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.addTab(actionBar.newTab().setText("Tab1")
.setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("Tab2")
.setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("Tab3")
.setTabListener(this));
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar()
.getSelectedNavigationIndex());
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
if (tab.getPosition() == 0) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Tab1).commit();
}
else if (tab.getPosition() == 1) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Tab2).commit();
}
else if (tab.getPosition() == 2) {
showProgress1();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, dashboardFrag).commit();
}
}
void showProgress1(){
nDialog = new ProgressDialog(MainActivity.this); //Here I get an error: The constructor ProgressDialog(PFragment) is undefined
nDialog.setMessage("Loading..");
nDialog.setTitle("Fetching Data");
nDialog.setIndeterminate(false);
nDialog.setCancelable(true);
nDialog.show();
}
#Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
}
Tab1.java
package com.example.trial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Tab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1, container, false);
return rootView;
}
}
Tab2.java
package com.example.trial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Tab2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab2, container, false);
return rootView;
}
}
DashboardTab.java
package com.example.trial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class DashboardTab extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.dashboard, container, false);
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rootView;
}
}
activity_main.xml
<FrameLayout android:id="#+id/container" android:layout_height="match_parent" android:layout_width="match_parent" tools:context=".MainActivity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
</FrameLayout>
tab1.xml
<?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:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab1"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
tab2.xml
<?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:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tab2"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
dashboard.xml
<?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:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="dashBoard"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
I didn't find something like you are telling, may be you are having issues with your phone memory, however an approach to show dialog when performing time consuming tasks through your code
public class DashboardTab extends Fragment {
private ProgressDialog nDialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.dashboard, container, false);
showProgress1();
YourTimeConsumingTask();
nDialog.dismiss();
return rootView;
}
private void YourTimeConsumingTask(){
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void showProgress1() {
nDialog = new ProgressDialog(getActivity()); // Here I get an error:
// The constructor
// ProgressDialog(PFragment)
// is undefined
nDialog.setMessage("Loading..");
nDialog.setTitle("Fetching Data");
nDialog.setIndeterminate(false);
nDialog.setCancelable(true);
nDialog.show();
}
}
I have a Fragment with a method setName() that changes an EditText text, by means of the setText function.
What is the best way to call that method from the activity that hosts that fragment by means of a ViewPager?
In other words, how can I access a Fragment's methods (which change that fragment's layout, for example) from the Activity that hosts that fragment by means of a ViewPager?
I am asking this because I have tried several ways, but always with errors.
Best way to do this, just call
CallingFragmentName fragment = (CallingFragmentName) viewPager
.getAdapter()
.instantiateItem(viewPager, viewPager.getCurrentItem());
It will re-instantiate your calling Fragment, so that it will not throw null pointer exception.
I know this is a little late, but I ran into the same problem and maybe it will help others if you already solved it.
The first problem I found with ViewPager is that it is almost impossible to get a reference to a fragment. The fragments are created dynamically in getItem() and therefore you can't set an ID and they are automatically re-taged by the swicher, so you can't find it by tag either. There are some ways out there to do it, but they are all workarounds. (Update data in ListFragment as part of ViewPager)
The way I solved it was using essentially a double Callback. Fragment A has an interface implemented by the Main Activity, the Main Activity has a interface implemented by Fragment B. On e.g. a button clink in Fragment A the callback function in Main Activity is called, which than in turn calls the callback in Fragment B. Look at the code below. I hope I posted everything and it will help. btw, I have only tried this with a ViewPager, but I assume it would work with any sort of Fragment communication.
Main Avtivity java:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity implements FragmentA.Caller {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
PassCallToB passOnToB = null;
FragmentManager myManager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
MyManager = fm;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if(position == 0) {
fragment = new FragmentA();
} else if (position == 1) {
fragment = new FragmentB();
passOnToB = (PassCallToB)fragment;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Frag A";
case 1:
return "Frag B";
}
return null;
}
public void setCallback() {
List<Fragment> frags = myManager.getFragments();
for(Fragment fragment : frags) {
if(fragment instanceof FragmentB){
passOnToB = (PassCallToB)fragment;
}
}
}
}
public interface PassCallToB {
public void passItOn();
}
#Override
public void CallB() {
if(passOnToB instanceof Fragment)
passOnToB.passItOn();
else {
mSectionsPagerAdapter.setCallback();
passOnToB.passItOn();
}
}
}
Main Activity xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<android.support.v4.view.PagerTitleStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
Fragment A java:
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class FragmentA extends Fragment {
Button btnCallB = null;
Caller listener = null;
public FragmentA() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) {
View rootView = inflater.inflate(R.layout.fragment_a, container, false);
btnCallB = (Button)rootView.findViewById(R.id.btnCallB);
btnCallB.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
listener.CallB();
}
});
return rootView;
}
public interface Caller {
public void CallB();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof FragmentActivity) {
listener = (Caller) activity;
} else {
throw new ClassCastException(activity.toString() + " must implemenet listener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Fragment A 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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="This is Fragment A" />
<Button
android:id="#+id/btnCallB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:text="Call Fragment B" />
</RelativeLayout>
Fragment B Java:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
public class FragmentB extends Fragment implements MainActivity.PassCallToB {
public FragmentB() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) {
View rootView = inflater.inflate(R.layout.fragment_b, container, false);
return rootView;
}
#Override
public void passItOn() {
Toast.makeText(getActivity(), "Hello from B", Toast.LENGTH_SHORT).show();
}
}
Fragment B 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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="This is Fragment B" />
</RelativeLayout>
You can access public methods within the fragments held by your ViewPager. You need to either (1) store a reference to the Fragment when you create it and add it to the list that will back your pager adapter or (2) you need to get a reference to the fragment from the pager adapter itself. For example:
Fragment fragmentA = null; //instance variable
fragmenA = new Fragment(); //whereever you instantiate your fragment
If your method is
public void setName(String args){
//do something
}
all you would do is call that method from the reference to the fragment held by your ViewPager
fragmentA.setName(args);
You pass whatever arguments you need just like calling a regular method. Note this ONLY works if you are calling a method within a fragment from its containing ViewPager or FragmentActivity. If you want to do the reverse, fragment to activity, you need to use an inerface.
Fragment
private static FragmentName instance;
public static synchronized FragmentName getInstance()
{
return instance;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance=this;
....
}
public void methodName()
{...}
Activity
FragmentName.getInstance().methodName();