2015-04-01 51 views
0

我在ViewPager中有WebView。當WebView開始加載數據時,它需要在某些URL上執行任務,從這些URL獲取一些ID,然後更新視圖。在AsyncTask後更新ViewPager中的WebView

我的問題是,如何更新ViewPagerWebView的最新內容? ViewPager位於Fragment之內。

這裏是我的代碼:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.fragment_detail_native, 
      container, false); 

    //.... non-relevant code removed 

    mViewPager = (ViewPager) view.findViewById(R.id.viewPager); 
    mCustomPagerAdapter = new CustomPagerAdapter(items, activity); 
    mViewPager.setAdapter(mCustomPagerAdapter); 
    mViewPager.setCurrentItem(position); 
    mViewPager.setOnPageChangeListener(new OnPageChangeListener() { 

     @Override 
     public void onPageSelected(int position) { 
      if (mTwoPane) 
       mOnPageSelectedListener.onPageSelected(position); 
     } 

     @Override 
     public void onPageScrolled(int position, float arg1, int arg2) { 
     } 

     @Override 
     public void onPageScrollStateChanged(int arg0) { 
     } 
    }); 

    return view; 
} 

CustomPagerAdapter類:

private class CustomPagerAdapter extends PagerAdapter { 

     List<Item> items = new ArrayList<Item>(); 
     LayoutInflater inflater; 
     Activity activity; 
     MyWebView mWebView = null; 

     public CustomPagerAdapter(List<Item> items2, Activity activity) { 
      this.items = items2; 
      this.activity = activity; 

      inflater = (LayoutInflater) activity 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     } 

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

     @Override 
     public boolean isViewFromObject(View view, Object object) { 
      return view == object; 
     } 

     @SuppressLint("SetJavaScriptEnabled") 
     @SuppressWarnings("deprecation") 
     @Override 
     public Object instantiateItem(ViewGroup container, int position) { 

      Item item = items.get(position); 

      View view = inflater.inflate(R.layout.item_detail_screen, 
        container, false); 
      mWebView = (MyWebView) view.findViewById(R.id.webView); 

      //... Webview settings code removed 
      //... Building HTML content removed 

      String content = item.content; 

      //... Some other HTML Content removed 

      html.append(content_prefix); 
      html.append(content_test); 
      html.append(content); 
      html.append(content_postfix); 

      html.append(htmlPostfix); 

      String htmlString = html.toString(); 
      htmlString = htmlString.replace("%", "&#37;"); 

      // At this point the htmlString has HTML data built. 
      // This data has some urls, that needs to be parsed to 
      // get VideoIDs and it is done by AsyncTask 

      // Method that calls AsyncTask 
      parseVideoLinks(htmlString); 

      mWebView.loadDataWithBaseURL("", htmlString, "text/html", "utf-8", 
        ""); 

      // ((ViewPager) container).addView((View) view, 0); 
      ((ViewPager) container).addView((View) view); 

      return view; 

     } 

     private void parseVideoLinks(String htmlString) { 
      UrlTask task = new UrlTask(htmlString); 
      task.execute(); 
     } 

     @Override 
     public void destroyItem(View collection, int position, Object view) { 
      ((ViewPager) collection).removeView((View) view); 
     } 

     public class UrlTask extends AsyncTask<Void, Void, String> { 

      String html = ""; 

      public UrlTask(String html) { 
       this.html = html; 
      } 

      @Override 
      protected String doInBackground(Void... params) { 

       Document doc = Jsoup.parse(html); 
       doc.select("img").attr("style", "width:100%") 
         .attr("height", "auto"); 
       doc.select("iframe").attr("style", "width:100%") 
         .attr("height", "auto"); 

       Elements paragragh_elements = doc.select("p"); 
       for (Element element : paragragh_elements) { 

        String text = element.text(); 

        if (text != null && !text.equalsIgnoreCase("")) { 

         if (text.contains("https://www.youtube.com/") 
           || text.contains("http://www.youtube.com/") 
           || text.contains("https://www.youtu.be/") 
           || text.contains("https://youtu.be/")) { 

          String expandedUrl = expandUrl(text); 
          if (expandedUrl != null) { 

           String[] splitUrl = expandedUrl.split("[?&]"); 

           for (String split : splitUrl) { 

            if (split.contains("v=")) { 
             String videoId = split 
               .replace("v=", ""); 

             Log.d(Const.DEBUG, "" + videoId); 

             Element new_element = constructElement(
               videoId, text); 
             element.replaceWith(new_element); 

            } 

           } 
          } else { 
           // embed 

          } 

         } else { 
          // not a youtube url 
         } 

        } 

       } 

       return doc.html(); 
      } 

      private Element constructElement(String videoId, String url) { 

       Element outerDivElement = new Element(Tag.valueOf("div"), ""); 
       outerDivElement.attr("style", "position:relative;"); 

       Element innerDivElement1 = new Element(Tag.valueOf("div"), ""); 
       Element aElement1 = new Element(Tag.valueOf("a"), ""); 
       aElement1.attr("href", url); 
       Element thumbImgElement = new Element(Tag.valueOf("img"), ""); 
       thumbImgElement.attr("src", 
         "http://img.youtube.com/vi/" + videoId + "/0.jpg") 
         .attr("style", "width:100%;"); 

       aElement1.appendChild(thumbImgElement); 
       innerDivElement1.appendChild(aElement1); 

       Element innerDivElement2 = new Element(Tag.valueOf("div"), ""); 
       innerDivElement2.attr("style", 
         "position:absolute; left:30px; top:30px;"); 
       Element aElement2 = new Element(Tag.valueOf("a"), ""); 
       aElement2.attr("href", url); 
       Element overlayImgElement = new Element(Tag.valueOf("img"), ""); 
       overlayImgElement.attr("src", 
         "file:///android_asset/images/play.png").attr("style", 
         "width:130%;"); 

       aElement2.appendChild(overlayImgElement); 
       innerDivElement2.appendChild(aElement2); 

       // Log.d(Const.DEBUG, "http://img.youtube.com/vi/" + videoId 
       // + "/0.jpg"); 

       outerDivElement.appendChild(innerDivElement1); 
       outerDivElement.appendChild(innerDivElement2); 

       return outerDivElement; 
      } 

      @Override 
      protected void onPostExecute(String result) { 
       super.onPostExecute(result); 

       // At this point, the result has the HTML content 
       // that i need to load the webview with. 
       // How do set webview data from here.. 

      } 

      public String expandUrl(String shortenedUrl) { 
       URL url; 
       String expandedURL = ""; 
       try { 
        url = new URL(shortenedUrl); 
        HttpURLConnection httpURLConnection = (HttpURLConnection) url 
          .openConnection(Proxy.NO_PROXY); 
        httpURLConnection.setInstanceFollowRedirects(false); 
        expandedURL = httpURLConnection.getHeaderField("Location"); 
        httpURLConnection.disconnect(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       return expandedURL; 
      } 

     } 

    } 

我怎麼可以設置網頁視圖一旦的AsyncTask完成,在onPostExecute()加載數據?

回答

0

我會在你的異步任務中創建一個接口(也許可以將它分成它自己的類),例如下面的那個;

public interface HtmlVideoLinksParsedListener 
{ 
    public void onHtmlVideoLinksParsed(String newHtml) 
} 

,然後讓你的活動來實現此接口(以及相應的方法),即

public class YourActivity implements HtmlVideoLinksParsedListener 
{ 
    //your activity code here 

    @Override 
    public void onHtmlVideoLinksParsed(String newHtml) 
    { 
    } 
} 

然後,只需傳遞活動,你的適配器,然後又到你的異步任務,並調用接口方法一旦HTML是準備傳遞迴的WebView即

public CustomPagerAdapter(List<Item> items2, Activity activity, HtmlVideoLinksParsedListener listener) { 
     this.items = items2; 
     this.activity = activity; 
     this.listener = listener; 

     inflater = (LayoutInflater) activity 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    private void parseVideoLinks(String htmlString) { 
      UrlTask task = new UrlTask(htmlString, listener); 
      task.execute(); 
    } 

那麼異步任務...

 //constructor 
     public UrlTask(String html, HtmlVideoLinksParsedListener listener) { 
      this.html = html; 
      this.listener = listener; 
     } 

      @Override 
      protected void onPostExecute(String result) { 
       super.onPostExecute(result); 

       listener.onHtmlVideoLinksParsed(result); 

      } 

然後在你的適配器設置一個方法來添加一個實例變量與一個在你的instantiateItem()方法中使用的html String並在適配器上調用notifyDataSetChanged()這樣的東西。

//in your actvity... 

@Override 
     public void onHtmlVideoLinksParsed(String newHtml) 
     { 
      mCustomPagerAdapter.setHtmlString(newHtml); 
      mCustomPagerAdapter.notifyDataSetChanged(); 
     } 

//then in your adapter 

//setter 
public setHtmlString(String newHtml) 
{ 
    this.htmlString = newHtml; 
} 

public Object instantiateItem(ViewGroup container, int position) { 
     //check for html string and use in web view else do normal processing via async task 

     if (htmlString!=null) 
     { 
     //add new html to webview here 
     } else { 
     //do normal html processing via async task here 

     } 
} 

希望這會有所幫助! :-)