Comment changer la vue à l'intérieur d'un fragment?
j'ai un fragment qui crée sa vue à l'intérieur de treateview comme vous vous y attendiez. Cependant je veux changer la vue régulièrement.
mon cas d'utilisation est que le fragment montre des données d'un service web. Lorsqu'un utilisateur choisit une option dans une liste (un autre fragment), ce fragment devrait passer à une barre de progression, puis une fois chargé, revenir à la vue des données.
je pourrais faire deux fragments-le fragment de chargement, et le fragment d'affichage, mais il semble que puisqu'il s'agit d'un événement encapsulé, je préfère le faire à l'intérieur du fragment.
fondamentalement, ce que je demande, c'est ce qu'est l'équivilent de setContentView à l'intérieur d'un fragment.
9 réponses
Vous pouvez utiliser Fragment.getView()
. Cela renvoie la vue du conteneur qui contient le Fragment
. Sur cette vue, vous pouvez appeler removeAllViews
. Puis construisez vos nouvelles vues et ajoutez - les à la vue que vous avez obtenu de getView()
.
http://developer.android.com/reference/android/app/Fragment.html#getView()
si pour une raison quelconque, vous voulez changer la vue entière du fragment (par exemple, une requête asynchrone D'URL qui va changer la vue sur le succès), vous pouvez soit utiliser la FragmentTransaction dans l'activité parent et créer un nouveau fragment à la volée.
ou vous pouvez garder le fragment et appeler une méthode de ce fragment qui se rafraîchira.
Exemple:
Dans l'activité parent, je construis et stocke une liste de fragments List<RefreshFragment> mFragmentList
.
Voici la classe de rafraîchissement (et tous mes fragments étendent celui - ci dans mon exemple) :
public class RefreshFragment extends Fragment {
protected Data data; // here your asynchronously loaded data
public void setData(Data data) {
this.data = data;
// The reload fragment code here !
if (! this.isDetached()) {
getFragmentManager().beginTransaction()
.detach(this)
.attach(this)
.commit();
}
}
}
Puis dans mon activité de rappel asynchrone, je peux appeler :
for (RefreshFragment f : mFragmentList) f.setData(data);
ainsi chaque fragment sera mis à jour avec les données correctes et le fragment actuellement attaché se mettra à jour immédiatement. Vous devez fournir votre propre vue de treateview dans les fragments bien sûr.
l'important est qu'un fragment puisse se recharger avec getFragmentManager()
.
vous pourriez utiliser un FrameLayout
pour passer de votre barre de progression à la vue des données, par exemple
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:id="@+id/cover_image"
android:scaleType="fitCenter"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ProgressBar android:id="@+id/cover_progress"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
onViewCreate()
vous stockerez alors les deux vues dans les champs d'instance
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
...
image = (ImageView) container.findViewById(R.id.cover_image);
progress = container.findViewById(R.id.cover_progress);
...
}
et quand vous voulez basculer entre les deux (n'oubliez pas de le faire dans votre UI/main thread), faites juste quelque chose comme
progress.setVisibility(View.INVISIBLE);
image.setVisibility(View.VISIBLE);
Créer un "dummy" vue par défaut
<?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" >
</LinearLayout>
gonflez la vue par défaut" factice " dans la méthode onCreateView du fragment et utilisez-la comme un espace réservé pour ajouter des vues au besoin
private LayoutInflater mInflater;
private ViewGroup mContainer;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
mInflater = inflater;
mContainer = container;
View v =inflater.inflate(R.layout.home_view,container,false);
placeholder = (ViewGroup) v;
return placeholder;
}
pour changer la vue à une nouvelle vue, vous supprimez d'abord toutes les vues précédentes, puis vous gonflez la nouvelle vue et ajoutez
View newView = mInflater.inflate(R.layout.custom_dash, mContainer, false);
placeholder.removeAllViews();
placeholder.addView(newView);
U peut utiliser le mouvement supprimer et ajouter. J'ai utilisé un Fragment dans lequel je peux charger n'importe quelle vue. Le constructeur du Fragment doit avoir un entier, cet entier est R. layout.... J'enlève le vieux fragment et j'en mets un nouveau. !!! Cela ne fonctionne que si vous faites de ce fragment une dynamique et pas dans la mise en page xml. Il suffit de créer quelque chose comme un R. id de LinearLayout.fragment_layout
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wundlist_fragmente);
Log.v("WoundListActivity", "WoundListActivity gestartet...");
Log.v("WoundListActivity", "Liste...");
//dynamisch hinzufügen...
wlf=new WoundListFragment();
fm.beginTransaction().add(R.id.fragment_layout,wlf).commit();
}
//If Menubutton Clicked change
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.itemaddwound){
Log.v("List", "neue Wunde Activity");
fm.beginTransaction().remove(wlf).commit();
fm.beginTransaction().add(R.id.fragment_layout, new NewWoundFragment()).commit();
}
return super.onOptionsItemSelected(item);
}
utilisation de la réponse Solostaran14s je le fais maintenant:
Interface:
public interface FragmentReattachListener {
public void reAttach();
}
Fragment:
public class MyFragment extends Fragment implements FragmentReattachListener {
//...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//...
App.registerFragmentReattachListener(this);
//...
}
//...
@Override
public void reAttach() {
FragmentManager f = getFragmentManager();
if (f != null) {
f.beginTransaction()
.detach(this)
.attach(this)
.commit();
}
}
}
à partir de la classe d'Application:
private static void reattachFragments() {
if (fragmentReattachListeners.size() > 0) {
for (FragmentReattachListener listener : fragmentReattachListeners) {
listener.reAttach();
}
}
}
Voici une solution plus simple: enregistrez le gonfleur et le conteneur que vous recevez dans onCreateView, et utilisez-les plus tard. Par exemple:
private LayoutInflater mInflater;
private ViewGroup mRootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mInflater = inflater;
mRootView = container;
return null;
}
public void someCallBackLater() {
// mRootView.removeAllViews(); // in case you call this callback again...
mInflater.inflate(R.layout.my_layout, mRootView);
}
Ce ce qui a fonctionné pour moi:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_recipe, container, false);
Button recipeBuyButton = (Button) v.findViewById(
R.id.recipe_buy_button);
Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/GE_SS_Two_Medium.otf");
recipeBuyButton.setTypeface(tf);
return v;
j'ai le même problème, fragment.getView () renvoie toujours null, bien que Fragment.onreateview a déjà été appelé avant
nous ne pouvons pas changer le contenu de fragment à l'exécution parce que mon fragment a été ajouté à ViewPager donc j'essaie d'utiliser une autre méthode pour obtenir la vue:
View view = viewPager.getChildAt(0);
TextView text = (TextView) (view.findViewById(R.id.textView));
text.setText("12345");
ce problème a été résolu, j'espère pouvoir vous aider