1

У меня есть панель навигации, где эти многочисленные варианты присутствуютКак сохранить состояние индикатора выполнения при переключении фрагментов?

  • Изображения материал
  • Видео Материала
  • Аудио Материал

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

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

Я пошел к решению использовать службу намерения и широковещательный приемник для заполнения индикатора выполнения, но в этом случае на каждом добавленном байте вещание будет сделано, это хорошая практика?

+0

Почему это потеряно? Вы создаете новый экземпляр фрагмента? – natario

+0

На самом деле я не прикрепляю и не отделяю фрагмент от каждой навигации, и поэтому на каждой навигации onCreateview() вызывается, что я теряю экземпляр строки выполнения в этом. – Hablu

+0

Насколько я помню, если вы используете popBackStack(), то созданный фрагмент не должен вызываться снова. – natario

ответ

1

Предыдущий ответ был недостаточно хорош, я составил новый, посмотрю, он работает очень хорошо.

Код состоит из базового класса для фрагментов, двух фрагментов, модели для хранения данных для элементов сетки и основного потока пользовательского интерфейса.

Базовый класс:

import android.app.Activity; 
import android.app.Fragment; 
import android.content.Context; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.GridView; 
import android.widget.ProgressBar; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 

import java.util.ArrayList; 

/** 
* Created by Movsar Bekaev on 20/09/2015. 
*/ 
public class GridFragment extends Fragment { 
    static ArrayList<xThumbnail> myInformation; 
    static Activity mActivity; 
    GAdapter adapter; 
    GridView grid; 

    enum fragment_names {FR1, FR2} 

    static fragment_names this_fragment_name; 

    public GridFragment() { 
     refresh(); 
    } 

    protected void refresh() { 
     if (grid == null) { 
      grid = new GridView(mActivity); 
      grid.setLayoutParams(new GridView.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); 
      grid.setBackgroundColor(Color.WHITE); 
      grid.setNumColumns(2); 
      grid.setColumnWidth(GridView.AUTO_FIT); 
      grid.setVerticalSpacing(5); 
      grid.setHorizontalSpacing(5); 
      grid.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); 
     } 
     adapter = new GAdapter(mActivity, myInformation); 
     grid.setAdapter(adapter); 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     refresh(); 
     return grid; 
    } 


    public class GAdapter extends BaseAdapter { 
     private Context mContext; 
     private ArrayList<xThumbnail> mInfo; 

     // Gets the context so it can be used later 
     public GAdapter(Context c, ArrayList<xThumbnail> info) { 
      mInfo = info; 
      mContext = c; 

     } 

     // Total number of things contained within the adapter 
     public int getCount() { 
      return mInfo.size(); 
     } 

     public xThumbnail getItem(int position) { 
      return mInfo.get(position); 
     } 

     // Require for structure, not really used in my code. Can 
     // be used to get the id of an item in the adapter for 
     // manual control. 
     public long getItemId(int position) { 
      return position; 
     } 

     public View getView(final int position, 
          View convertView, ViewGroup parent) { 

      View v; 
      if (convertView == null) { 
       LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = inflater.inflate(R.layout.thumbnail, null); 
       final TextView tv = (TextView) v.findViewById(R.id.tvClickMe); 
       final ProgressBar pb = (ProgressBar) v.findViewById(R.id.prgb_progress); 
       pb.setProgress(mInfo.get(position).getProgress()); 
       tv.setText(mInfo.get(position).getProgress() + ""); 
       mInfo.get(position).setProgressBar(pb); 
       mInfo.get(position).setTextView(tv); 
       tv.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         runOp(mInfo.get(position), position, this_fragment_name); 
        } 
       }); 
      } else { 
       v = convertView; 
      } 
      return v; 
     } 
    } 

    private void runOp(final xThumbnail x, final int position, final fragment_names f_name) { 
     if (x.xt == null) { 
      x.xt = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        for (int i = x.getProgress(); i <= 100; i++) { 

         // UNCOMMENT IF YOU WANT TO STOP THE PROCESS AFTER SWITCHING 
         // if ((f_name == this_fragment_name) && !mThread.isInterrupted()) { 
         final int progress = i; 
         mActivity.runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           x.setProgressBar(adapter.getItem(position).getProgressBar()); 
           x.setTextView(adapter.getItem(position).getTextView()); 
           x.setProgress(progress); 
           x.getProgressBar().setProgress(progress); 
           x.getTextView().setText(progress + ""); 
           // ARBITRARY CHANGE OF MYINFORMATION 
           // JUST TO SHOW THAT IT WORKS 
           if (progress == 20) { 
            myInformation.get(3).setProgress(12); 
            refresh(); 
           } 
           // ********************************** 
          } 
         }); 
         try { 
          Thread.sleep(150); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
         // } else { 
         //  return; 
         // } 
        } 
       } 
      }); 
     } 
     if (!x.xt.isAlive()) 
      x.xt.start(); 
    } 
} 

fr1.java:

public class fr1 extends GridFragment { 
    static ArrayList<xThumbnail> fr1Info; 

    public static fr1 newInstance(Activity act) { 
     mActivity = act; 
     return new fr1(); 
    } 

    @Override 
    protected void refresh() { 
     if (fr1Info == null || fr1Info.size() == 0) { 
      fr1Info = new ArrayList<>(); 
      for (int i = 0; i < 10; i++) { 
       xThumbnail x; 
       x = new xThumbnail(); 
       fr1Info.add(x); 
      } 

     } 
     myInformation = fr1Info; 
     super.refresh(); 
    } 
} 

fr2.java:

public class fr2 extends GridFragment { 
    static ArrayList<xThumbnail> fr2Info; 

    public static fr2 newInstance(Activity act) { 
     mActivity = act; 
     return new fr2(); 
    } 

    @Override 
    protected void refresh() { 
     if (fr2Info == null || fr2Info.size() == 0) { 
      fr2Info = new ArrayList<>(); 
      for (int i = 0; i < 10; i++) { 
       xThumbnail x; 
       x = new xThumbnail(); 
       fr2Info.add(x); 
      } 
     } 
     myInformation = fr2Info; 
     super.refresh(); 
    } 
} 

xThumbnail.java (модель):

public class xThumbnail {  
    private int prgb_value = 0; 
    private ProgressBar pb; 
    private TextView tv; 
    public Thread xt; 

    public void setProgress(Integer i) { 
     prgb_value = i; 
    } 

    public Integer getProgress() { 
     return prgb_value; 
    } 

    public void setProgressBar(ProgressBar prb) { 
     pb = prb; 
    } 

    public ProgressBar getProgressBar() { 
     return pb; 
    } 

    public void setTextView(TextView tv) { 
     this.tv = tv; 
    } 

    public TextView getTextView() { 
     return tv; 
    } 
} 

MainActivity.java:

public class MainActivity extends AppCompatActivity { 
     Button btn_one, btn_two; 
     fr1 mFr1; 
     fr2 mFr2; 
     FragmentManager fm = getFragmentManager(); 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
      btn_one = (Button) findViewById(R.id.btn_one); 
      btn_two = (Button) findViewById(R.id.btn_two); 

      mFr1 = (fr1) fm.findFragmentByTag("fr1"); 
      mFr2 = (fr2) fm.findFragmentByTag("fr2"); 
      final FrameLayout frameLayout = (FrameLayout)findViewById(R.id.frLayout); 

      btn_one.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       GridFragment.this_fragment_name= GridFragment.fragment_names.FR1; 

       if (mFr1 == null) { 
        mFr1 = fr1.newInstance(MainActivity.this); 
        fm.beginTransaction().add(R.id.frLayout, mFr1, "fr1").commit(); 
       } else { 
        fm.beginTransaction().detach(mFr1).commit(); 
        fm.beginTransaction().attach(mFr1).commit(); 

       } 
      } 
     }); 

     btn_two.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       GridFragment.this_fragment_name= GridFragment.fragment_names.FR2; 

       if (mFr2 == null) { 
        mFr2 = fr2.newInstance(MainActivity.this); 
        fm.beginTransaction().add(R.id.frLayout, mFr2, "fr2").commit(); 
       } else{ 
        fm.beginTransaction().detach(mFr2).commit(); 
        fm.beginTransaction().attach(mFr2).commit(); 

       } 
      } 
     }); 
     } 
    } 

activity_main.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:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="1" 
     android:id="@+id/btn_one" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="2" 
     android:id="@+id/btn_two" 
     android:layout_alignParentBottom="true" 
     android:layout_alignRight="@+id/prgb_uni" 
     android:layout_alignEnd="@+id/prgb_uni" /> 

    <ProgressBar 
     style="?android:attr/progressBarStyleHorizontal" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/prgb_uni" 
     android:layout_alignParentBottom="true" 
     android:layout_marginBottom="40dp" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentEnd="true" /> 

    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_alignParentTop="true" 
     android:id="@+id/frLayout"></FrameLayout> 


</RelativeLayout> 

миниатюр.XML:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ProgressBar 
     style="?android:attr/progressBarStyleHorizontal" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:id="@+id/prgb_progress" /> 

    <TextView 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:gravity="center" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:text="ClickMe!" 
     android:id="@+id/tvClickMe" 
     android:layout_gravity="center_horizontal" 
     android:textIsSelectable="false" /> 
</FrameLayout> 

Что делает: Мы имеем здесь один базовый класс, он работает с представлением мнений и заселение прогресс бары. В нем есть поле для работы с текущими элементами (которые содержат значения строки выполнения), каждый раз, когда мы переключаемся между фрагментами, это поле обновляется до соответствующих значений Fragment1 или Fragment2, эти фрагменты имеют статические поля для хранения своих собственных данных, чтобы они могли быть изменено и использовано.

Вещь с нитью и некоторым другим кодом - это просто показать, что это работает и для лучшего понимания.

Надеюсь, это поможет.

PoC - https://youtu.be/uKGeX40z_mA :)

+0

Я не могу взять индикатор выполнения в фрагменте. Как я сказал, каждый фрагмент имеет вид сетки, который содержит список представлений, и для каждого представления есть индикатор выполнения. – Hablu

+0

Тогда вы не можете создать класс для хранения ваших индикаторов выполнения и их значений и сделать их массив для каждого фрагмента? –

+0

Если я возьму статическую переменную, я должен взять много, поскольку у меня много просмотров во фрагменте. если я возьму одну статическую переменную, она может быть изменена другим значением обновления хода. – Hablu

1

В качестве абстрактного плана вы можете добавить загрузку Service в свое приложение и позволить ему загрузить ваши материалы.

Для связи с этой услугой вы можете объявить ее как услугу bind-able, чтобы всякий раз, когда пользователь переключался на этот фрагмент, ваша деятельность может привязываться к этой службе и видеть, что происходит.

Используя этот способ, вы можете сообщить о ходе загрузки пользователю, а также вам больше не нужно отправлять трансляции.

+0

У вас есть ссылка, где я могу найти связанные примеры, что вы пытаетесь объяснить. – Hablu

+0

@Hablu http://developer.android.com/guide/components/bound-services.html –

Смежные вопросы