2014-07-22 30 views
1

我的應用程序從Web服務中爲每個用戶生成不同部分的數據。然後,我將使用這些部分使用FragmentPagerAdapter創建選項卡。FragmentPagerAdapter動態選項卡和頁數

我已經使用異步任務從Web服務中提取數據。然而,重寫的方法,如FragmentPagerAdapter中的getCount()和getPageTitle()在我的asynctask之前執行並完成其工作。我該如何防止這種情況發生,並根據從Web服務獲取的數據生成動態數量的選項卡及其標題名稱?

在我怎樣才能創建一個基於數據的標籤和標題的動態數量換句話說從Web服務

我對FragmentPagerAdapter如下代碼獲取。正如你所看到的,我已經硬編碼了標籤的數量和標題名稱。

public class SectionsPagerAdapter extends FragmentPagerAdapter{ 

    private boolean proceedStatus = false; 
    private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx"; 

    //list of fragments need to be added dynamically 
    public final ArrayList<Fragment> screens = new ArrayList<Fragment>(); 



    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 

    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a DummySectionFragment (defined as a static inner class 
     // below) with the page number as its lone argument. 
     Fragment fragment = new SectionFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(SectionFragment.ARG_SECTION_NUMBER, position + 1); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public int getCount() { 
     return 2; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     Locale l = Locale.getDefault(); 
     switch (position) { 
     case 0: 
      return "Camera".toUpperCase(l); 
     case 1: 
      return getString(R.string.title_section2).toUpperCase(l); 
     case 2: 
      return getString(R.string.title_section3).toUpperCase(l); 
     case 3: 
      return "SECTION 4"; 
     } 
     return null; 
    } 

    //setting the section title 
    private void setSectionTitle(){ 

    } 

    //count the number of sections 
    private int countNumberofSections(){ 
     int numberOfSection = 0; 
     return numberOfSection; 
    } 
} 

然後,我有我的代碼片段如下它具有呼叫者的異步任務

public static class SectionFragment extends Fragment implements OnTaskCompleted { 
    /** 
    * The fragment argument representing the section number for this 
    * fragment. 
    */ 
    private Slider adapter; 
    private ViewPager viewPager; 
    public static final String ARG_SECTION_NUMBER = "section_number"; 
    Button thumbUpBut; 
    Button thumbDownBut; 
    Button captureButton; 
    ImageView genImage; 
    TextView genCaption; 
    private Camera mCamera; 
    private CameraPreview mPreview; 
    private static File mediaFile; 
    private ProgressDialog progress; 
    private static String imageSaveLocation; 
    private static String file_name_without_extension; 
    private ImageView imageView; 
    private Button uploadButton; 
    private Button cancelButton; 
    private Collection<Place> places = null; 
    private Collection<Happenings> events = null; 
    private Collection<General> general = null; 
    private ArrayList<String> sections; 

    public int getNumberOfPages(){ 
     return sections.size(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main_dummy,container, false); 
     TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label); 
     dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); 

     FeedRequest task = new FeedRequest(this); 
     task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 

     captureButton = (Button) rootView.findViewById(R.id.button_capture); 
     captureButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       takePhoto(); 
      } 
     }); 

     thumbUpBut = (Button) rootView.findViewById(R.id.thumbUp); 
     thumbUpBut.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) { 
       Log.v("thumbPress", "thumbPressUp"); 
       thumb("up"); 
      } 
     }); 

     thumbDownBut = (Button) rootView.findViewById(R.id.thumbDown); 
     thumbDownBut.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) { 
       Log.v("thumbPress", "thumbPressDown"); 
       thumb("down"); 
      } 
     }); 

     //allocating the activity one to the camera 
     if(getArguments().getInt(ARG_SECTION_NUMBER) == 1){ 
      mCamera = getCameraInstance(); 
      mPreview = new CameraPreview(this.getActivity(), mCamera); 
      FrameLayout preview = (FrameLayout)rootView.findViewById(R.id.camera_preview); 
      preview.addView(mPreview); 

      //hide buttons 
      thumbDownBut.setVisibility(rootView.INVISIBLE); 
      thumbUpBut.setVisibility(rootView.INVISIBLE); 
     }else{ 
      thumbDownBut.setVisibility(rootView.VISIBLE); 
      thumbUpBut.setVisibility(rootView.VISIBLE); 
      captureButton.setVisibility(rootView.INVISIBLE); 
     } 

     viewPager = (ViewPager) rootView.findViewById(R.id.pager); 
     return rootView; 
    } 

    //take photo function 
    private void takePhoto() { 

     //get coordinates of the location 
     UserLocation userLocation = new UserLocation(); 
     userLocation.getUserLocation(getActivity()); 
     coordinates[0] = userLocation.longitude; 
     coordinates[1] = userLocation.latitude; 

     PictureCallback pictureCB = new PictureCallback() { 
      public void onPictureTaken(byte[] data, Camera cam) { 
       new SavePhotoAndMetadata().execute(data); 
       cam.startPreview(); 
      } 
     }; 
     mCamera.takePicture(null, null, pictureCB); 
    } 

    //get camera instance 
    private Camera getCameraInstance() { 
     Camera camera = null; 
     try { 
      camera = Camera.open(); 
     } catch (Exception e) { 
      // cannot get camera or does not exist 
     } 
     return camera; 
    } 

    //get the media out 
    private static File getOutputMediaFile() { 
     File mediaStorageDir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img"); 
     if (!mediaStorageDir.exists()) { 
      if (!mediaStorageDir.mkdirs()) { 
       Log.d("MyCameraApp", "failed to create directory"); 
       return null; 
      } 
     } 
     // Create a media file name 
     String timeStamp = (DateFormat.format("dd-MM-yyyy hh:mm:ss", new java.util.Date()).toString()); 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); 
     file_name_without_extension = "IMG_" + timeStamp; 
     imageSaveLocation = mediaFile.toString(); 
     return mediaFile; 
    } 

    //saving the image and metadata together 
    class SavePhotoAndMetadata extends AsyncTask<byte[], String, String> { 
     @Override 
     protected String doInBackground(byte[]... data) { 
      File picFile = getOutputMediaFile(); 
      if (picFile == null) { 
       return null; 
      } 

      byte[] photoData = data[0]; 
      try { 
       //save the image 
       FileOutputStream fos = new FileOutputStream(picFile); 
       fos.write(photoData); 
       fos.close(); 
      } catch (FileNotFoundException e) { 
       e.getStackTrace(); 
      } catch (IOException e) { 
       e.getStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      progress = new ProgressDialog(getActivity()); 
      progress.setMessage("Saving Picture..Please wait..."); 
      progress.show(); 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      progress.dismiss(); 
      imagePreviewDialog(); 
     } 
    } 

    //save image metadata in async task 
    class SaveMetadataTask extends AsyncTask<Void, String, Void> { 

     @Override 
     protected Void doInBackground(Void... params) { 
      serializeDeserialize.serializeData("This is for testing", file_name_without_extension, Double.toString(coordinates[0]), Double.toString(coordinates[1]), deviceId, deviceEmail); 
      return null; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected void onPostExecute(Void v) { 

     } 
    } 

    //image preview dialog and its functionality 
    private void imagePreviewDialog(){ 
     //setting the bitmap 
     Bitmap bmp = BitmapFactory.decodeFile(mediaFile.toString()); 

     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     builder.setTitle("Image Preview"); 
     builder.setCancelable(false); 
     LayoutInflater inflater = getActivity().getLayoutInflater(); 
     ViewGroup vg = (ViewGroup)inflater.inflate(R.layout.sanp_preview_layout, null); 
     ImageView image = (ImageView) vg.findViewById(R.id.imageView); 
     image.setImageBitmap(rotateBitmap(bmp)); 
     builder.setView(vg); 

     //buttons 
     builder.setPositiveButton("Upload",new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int whichButton) { 

        if(checkInternetConnection.haveNetworkConnection(sContext)){ 
         //upload the image 
         uploadImage(); 

         //save image metadata 
         new SaveMetadataTask().execute(); 
        }else{ 
         Toast.makeText(sContext, "Error! No internet connection detected. Image will be uploaded on an active internet connection", Toast.LENGTH_LONG).show(); 
         new SaveMetadataTask().execute(); 
        } 
       } 
     }); 

     builder.setNegativeButton("Discard",new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int whichButton) { 
        discardImage(mediaFile.toString()); 
        dialog.dismiss(); 
       } 
     }); 
     builder.show(); 
    } 

    private Bitmap rotateBitmap(Bitmap image){ 
     int width=image.getHeight(); 
     int height=image.getWidth(); 

     Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig()); 

     for (int y=width-1;y>=0;y--) 
      for(int x=0;x<height;x++) 
       srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y)); 
     return srcBitmap; 

    } 

    //device email 
    private String getDeviceEmail(){ 
     AccountManager accountManager = AccountManager.get(sContext); 
     Account[] account = accountManager.getAccountsByType("com.google"); 

     //device email 
     for(Account accLoop : account){ 
      deviceEmail = accLoop.name; 
     } 
     return deviceEmail; 
    } 

    //upload image to the server 
    private void uploadImage(){ 

     //save metadata 

     //call upload service 
     Intent intent = new Intent(sContext, HttpUploader.class); 
     Bundle loc = new Bundle(); 
     loc.putDoubleArray("ss", coordinates); 
     intent.putExtra("url", PHOTO_UPLOAD); 
     intent.putExtra("paths", mediaFile.toString()); 
     intent.putExtra("deviceid", deviceId); 
     intent.putExtra("deviceemail", getDeviceEmail()); 
     intent.putExtra("posttext", "This is for testing"); 
     intent.putExtra("filename", file_name_without_extension); 
     intent.putExtra("geo", loc); 
     sContext.startService(intent); 

     Toast.makeText(getActivity(), "Your image is being uploaded", Toast.LENGTH_LONG).show(); 
    } 

    //discard image when the discard button is pressed 
    private void discardImage(String imagePath){ 
     File file = new File(imagePath); 
     try{ 
      file.delete(); 
     }catch(Exception e){ 
      Log.e("IMAGE_DELETION_ERROR", e.toString()); 
     } 
    } 

    @Override 
    public void onTaskCompleted(boolean status, String message) { 
     // TODO Auto-generated method stub 

     Log.e("onTaskCompleted", "success" + status); 

     if (message == "tumb UP success") { 
      thumbUpBut.setSelected(true); 
      thumbDownBut.setSelected(false); 
      Log.e("tumb", "tumb"); 

     } else if (message == "tumb DOWN success") { 
      thumbDownBut.setSelected(true); 
      thumbUpBut.setSelected(false); 
      Log.e("tumb", "tumb"); 
     } 
    } 

    //listener for fetching main objects 
    @Override 
    public void onFeedCompleted(ArrayList<Posts> postArray, Multimap<String, Object> multiMap) { 
     // TODO Auto-generated method stub 
     numberOfPages = postArray.size(); 
     adapter = new Slider(getActivity(), postArray, getContext()); 
     viewPager.setAdapter(adapter); 
     // displaying selected image first 
     viewPager.setCurrentItem(postArray.size()); 

     //saving the keyset 
     Set<String> keys = multiMap.keySet(); 
     sections = new ArrayList<String>(); 

     //sorting the categories and creating the category list 
     for(String key:keys){ 

      //getting category list 
      if(!sections.contains(keys)){ 
       sections.add(key); 
      } 

      //sorting categories 
      if(key.equals("Place")){ 
       places.add((Place) multiMap.get(key)); 
      }else if(key.equals("Events")){ 
       events.add((Happenings) multiMap.get(key)); 
      }else if(key.equals("General")){ 
       general.add((General) multiMap.get(key)); 
      } 
     } 
    } 

    //adding the pages to the adaptor dynamically 
    public void addPagesDynamically(){ 

    } 
} 

//create the parent directory 
private void createParentDiectory(){ 
    File dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap"); 
    if(!(dir.exists() && dir.isDirectory())) { 
     dir.mkdirs(); 
    } 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle presses on the action bar items 
    switch (item.getItemId()) { 
    case R.id.action_post: 
     openPost(); 
     return true; 
    case R.id.action_settings: 
     // openSettings(); 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 

public void openPost() { 
    /* 
    Intent i = new Intent(getApplicationContext(), PhotoActivity.class); 
    startActivity(i); 
    */ 
} 

public static void thumb(String type) { 
    SectionFragment d = new SectionFragment(); 
    PostThumb task = new PostThumb(type, d); 
    task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
} 

//broadcast receiver for picture upload 
public class MyWebRequestReceiver extends BroadcastReceiver { 

    public static final String PROCESS_RESPONSE = "asia.ceynet.intent.action.PROCESS_RESPONSE"; 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     //String responseString = intent.getStringExtra(HttpUploader.RESPONSE_STRING); 
     String reponseMessage = intent.getStringExtra(HttpUploader.RESPONSE_MESSAGE); 
     String responseStatus = intent.getStringExtra(HttpUploader.RESPONSE_STATUS); 
     String file_to_be_deleted = intent.getStringExtra(HttpUploader.FILE_NAME_WITHOUT_EXTENSION); 
     Toast.makeText(getApplicationContext(), reponseMessage + " - " + file_to_be_deleted + ".jpg", Toast.LENGTH_LONG).show(); 

     //if uploaded successfully delete or image and metadata 
     if(responseStatus.equals("true")){ 
      File temp_image_dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".jpg"); 
      File metadata_file = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".ser"); 
      try{ 
       temp_image_dir.delete(); 
       metadata_file.delete(); 
      }catch(Exception e){ 
       Log.e("IMAGE_DELETION_ERROR", e.toString()); 
      } 
     } 
    } 
} 

回答

1

當芬蘭拉力異步數據,提供適配器用新的數據,並調用.notifyDataSetChanged ()在該適配器實例上,框架將更新頁面並自行計數。

如果您希望更詳細的解釋發佈您的FragmentPagerAdapter實現。

+0

我發佈了我的代碼。請檢查 – Yrol

+0

你能解釋一下嗎?從我現在看到你現在有兩個相同的片段。您處理片段中的數據,並且處理後的數據更新時,您希望將其他(相同的?)片段添加到視圖尋呼機?基本上你需要尋呼機適配器中的數據結構(如屏幕列表變量),並在getCount()方法中動態返回適當的大小。希望這是有道理的。 – skipper3k

+0

在加載片段之前,我想執行包括「onFeedCompleted」和「onTaskCompleted」在內的「OnTaskCompleted」(在SectionFragment中實現)接口方法。然後基於這些數據,我想生成這些片段 – Yrol

1

首先,讓我道歉,如果我沒有讓自己足夠清楚,因爲這是我第一次參加這裏的一個或多個。但我會一直在這裏回答與此答案有關的疑問,並澄清我的言論引起的任何混淆。

由於您使用的是碎片,所以我假設您必須將碎片包含在某個活動中(例如MainActivity.java)。
您需要什麼,可以在包含片段的活動中完成。 這裏是onCreate方法的MainActivity

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    FragmentManager fragmentManager = getSupportFragmentManager(); 

    //Instance of viewpager included inside activity_main.xml 
    viewPager = (ViewPager) findViewById(R.id.vpMain); 


    SectionsPagerAdapter adapter = new SectionsPagerAdapter (fragmentManager); 

    //Adding some fragments right from the beginning, you could ignore it if not needed. 
    addFragments(); 

    //This `OnPageChangeListener` will do the trick for you. 
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

     } 

     @Override 
     public void onPageSelected(int position) { 
      //Show the title of fragment 
      Toast.makeText(MainActivity.this, adapter.screens.get(position), Toast.LENGTH_SHORT).show(); 

      //If fragment being loaded is later than the first one, 
      // then add one more fragment after the last fragment to the adapter. 
      // integer currentPosition is declared as a field, outside onCreate method and initially set to 0. 
      if(position>currentPosition){ 
       currentPosition+=1; 
       adapter.addFragment(new SectionFragment(), "Fragment"+String.valueOf(position+3)); 
       adapter.notifyDataSetChanged(); 
      }else{ 
       currentPosition--; 
      } 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 

     } 
    }); 


} // onCreate ends here. 

裏面的示例代碼創建內部的這種方法,您MainActivity(只添加3個片段,讓您的應用程序中的頭開始。

private void addFragments(){ 
    adapter.addFragment(new SectionFragment()); 
    adapter.addFragment(new SectionFragment()); 
    adapter.addFragment(new SectionFragment()); 
} 

然後修改SectionsPagerAdaptergetItemgetCount方法如下:

public class SectionsPagerAdapter extends FragmentPagerAdapter{ 

private boolean proceedStatus = false; 
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx"; 

//list of fragments need to be added dynamically 
public final ArrayList<Fragment> screens = new ArrayList<Fragment>(); 



public SectionsPagerAdapter(FragmentManager fm) { 
    super(fm); 

} 

@Override 
public Fragment getItem(int position) { 
    return screens.get(position); 
} 

@Override 
public int getCount() { 
    return screens.size(); 
} 

//This method will dynamically add a fragment each time it is called. 
public void addFragment(Fragment fragment) { 
    screens.add(fragment); 
} 

現在,不需要在SectionFragment類中完成與「向列表中添加新片段」相關的任何工作。

相關問題