java - usar - ¿Por qué acceder a TextView de un Fragmento dentro de Activity arroja un error
viewpager not showing fragment (4)
Clase
MainActivity
:
/* all necessary imports */
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
/* Other variable initialized here... */
FragOne fo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fo.setTextViewText("This is added from Activity");
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragOne(), "My Tracker");
adapter.addFragment(new FragTwo(), "Team Tracker");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
Clase de
Fragment
:
/* all necessary imports */
public class FragOne extends Fragment {
TextView tvCName;
public FragOne() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_frag_one, container, false);
return view;
//return inflater.inflate(R.layout.fragment_frag_one, container, false);
}
@Override
public void onViewCreated(View view , Bundle savedInstanceState) {
tvCName = (TextView) view.findViewById(R.id.tvctq);
}
public void setTextViewText(String value){
tvCName.setText(value);
}
}
Fragment
diseño XML:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mytip.FragOne">
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvctq" />
</FrameLayout>
Estoy tratando de acceder a
TextView
dentro del
Fragment
de
MainActivity
esta manera:
FragOne fo;
fo.setTextViewText("This is added from Activity");
Sigo recibiendo un
NullPointerExceptionError
.
Miré todos los artículos para ver cómo acceder, sin embargo, ninguno de ellos me ayudó.
¿Puede alguien decirme qué estoy haciendo mal y cómo solucionarlo?
También planeo agregar otras
View
dentro de mi
Fragment
que necesitaría acceder en el futuro.
Debe prestar atención al ciclo de vida de la actividad: parece que está configurando todo correctamente, pero comete algunos errores al acceder a la instancia correcta del fragmento en el momento en que está realmente listo. Cosas que deberías hacer
-
Obtenga una instancia adecuada del fragmento de su
ViewPager
, como sugirió @ginomempin; -
Solo intente configurar su texto no antes de que se haya llamado a sus actividades en el método
onStart
: generalmente loonResume
métodoonResume
(puede anularlo si aún no lo ha hecho). Hacerlo en el métodoonResume
en la actividad asegura que su Fragment ya haya pasado por su ciclo de vida hastaonResume
también, y los datos se actualizarán si se han puesto en segundo plano anteriormente.
Debe usar su método de fábrica Fragment al crear su Fragment en su actividad. Por favor ver más abajo:
** **
Pila posterior
** **
La transacción en la que se modifican los fragmentos se puede colocar en una pila interna de la actividad propietaria. Cuando el usuario vuelve a presionar en la actividad, todas las transacciones en la pila posterior se eliminan antes de que finalice la actividad.
Por ejemplo, considere este fragmento simple que se instancia con un argumento entero y lo muestra en un TextView en su IU:
public static class CountingFragment extends Fragment {
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static CountingFragment newInstance(int num) {
CountingFragment f = new CountingFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance''s number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment''s UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
return v;
}
}
Una función que crea una nueva instancia del fragmento, reemplazando cualquier instancia de fragmento actual que se muestre y empujando ese cambio a la pila posterior, podría escribirse como:
void addFragmentToStack() {
mStackLevel++;
// Instantiate a new fragment.
Fragment newFragment = CountingFragment.newInstance(mStackLevel);
// Add the fragment to the activity, pushing this transaction
// on to the back stack.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.simple_fragment, newFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
Después de cada llamada a esta función, hay una nueva entrada en la pila, y al presionar hacia atrás la abrirá para devolver al usuario al estado anterior en que se encontraba la IU de actividad.
Fuente: https://developer.android.com/reference/android/app/Fragment.html
Necesita obtener la misma instancia de
FragOne
desde el visor.
Primero, solo puede acceder a la instancia de
FragOne
después de configurar ViewPager.
Entonces, intente esto:
fo = adapter.getItem(0)
Nota:
Como ya tiene fragmentos, sería mejor dejar que el fragmento mismo maneje las acciones relacionadas con la interfaz de usuario (como configurar la vista de texto) en lugar de hacerlo desde la Actividad.
Porque
fo
no se ha inicializado en el siguiente fragmento de código:
FragOne fo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fo.setTextViewText("This is added from Activity");
...
}
fo.setTextViewText()
razonablemente arroja
NPE
.