Подтвердить что ты не робот

Как изменить представление внутри фрагмента?

У меня есть фрагмент, который создает его представление внутри onCreateView, как вы ожидали. Однако я хочу периодически менять представление.

Моим вариантом использования является то, что фрагмент показывает некоторые данные из веб-службы. Когда пользователь выбирает опцию из списка (другой фрагмент), этот фрагмент должен переключиться на индикатор выполнения, а затем после загрузки переключиться обратно в представление данных.

Я мог бы сделать два фрагмента - фрагмент загрузки и фрагмент отображения, но кажется, что, поскольку это инкапсулированное событие, я предпочел бы сделать все это внутри одного фрагмента.

В основном то, что я прошу, является тем, что является эквивалентом setContentView внутри фрагмента.

4b9b3361

Ответ 1

Вы можете использовать Fragment.getView(). Это возвращает вид контейнера, который содержит Fragment. С этой точки зрения вы можете вызвать removeAllViews. Затем создайте новые представления и добавьте их в представление, которое вы получили от getView().

http://developer.android.com/reference/android/app/Fragment.html#getView()

Ответ 2

Если по какой-либо причине вы хотите изменить представление всего фрагмента (например, асинхронный запрос URL-адреса, который изменит представление на успех), вы можете либо использовать FragmentTransaction в родительской активности, либо создать новый фрагмент на лету.

Или вы можете сохранить фрагмент и вызвать метод этого фрагмента, который обновится. Пример: В родительской активности я создаю и сохраняю список фрагментов List<RefreshFragment> mFragmentList.

Вот класс RefreshFragment (и все мои фрагменты расширяют его в моем примере):

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();
        }
    }
}

Затем в моей работе асинхронный обратный вызов я могу вызвать:

for (RefreshFragment f : mFragmentList) f.setData(data);

Таким образом, каждый фрагмент будет обновлен с правильными данными, и текущий прикрепленный фрагмент будет немедленно обновляться. Конечно, вы должны предоставить вам собственный onCreateView.

Важно то, что фрагмент может перезагрузить себя с помощью getFragmentManager().

Ответ 3

Вы можете использовать FrameLayout для переключения между индикатором выполнения и представлением данных, например

<?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() вы сохраните оба представления в полях экземпляров

public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
    ...
    image = (ImageView) container.findViewById(R.id.cover_image);
    progress = container.findViewById(R.id.cover_progress);
    ...
}

и всякий раз, когда вы хотите переключаться между ними (не забудьте сделать это в своем пользовательском интерфейсе/главном потоке), просто сделайте что-то вроде

progress.setVisibility(View.INVISIBLE);
image.setVisibility(View.VISIBLE);

Ответ 4

Создайте представление "dummy" по умолчанию

<?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>

Разверните представление "dummy" по умолчанию в методе onCreateView и используйте его в качестве заполнителя для добавления просмотров по мере необходимости

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;
}

Чтобы изменить представление на новый вид, вы сначала удалите все предыдущие виды, затем раздуваете новое представление и добавляете

View newView = mInflater.inflate(R.layout.custom_dash, mContainer, false);
placeholder.removeAllViews();
placeholder.addView(newView);

Ответ 5

U может использовать Transaction remove и add. Я использовал фрагмент, в котором я могу загрузить любое представление. Конструктор фрагмента должен иметь целое число, что целое число R.layout.... Я просто удаляю старый фрагмент и добавляю несколько новых. !!! Он работает, только если вы сделаете этот фрагмент динамическим, а не в макете xml. Просто создайте что-то вроде LinearLayout R.id.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);
}

Ответ 6

Используя ответ Solostaran14s, я делаю это сейчас:

Интерфейс:

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();
        }
    }

}

из класса Application:

private static void reattachFragments() {
        if (fragmentReattachListeners.size() > 0) {
            for (FragmentReattachListener listener : fragmentReattachListeners) {
                listener.reAttach();
            }
        }
    }

Ответ 7

Здесь более простое решение: сохраните надув и контейнер, который вы получите в onCreateView, и используйте их позже. Например:

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);
}

Ответ 8

Это сработало для меня:

@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;

Ответ 9

У меня одна и та же проблема, фрагмент .getView() всегда возвращает null, хотя Fragment.onCreateView уже вызывается перед

мы не можем изменить содержимое фрагмента во время выполнения, потому что мой фрагмент был добавлен в ViewPager, поэтому я пытаюсь использовать другой метод для просмотра:

 View view  =  viewPager.getChildAt(0);
 TextView text = (TextView) (view.findViewById(R.id.textView));
 text.setText("12345");

Теперь эта проблема была решена, надеюсь, вам поможет