在AsyncTask之后更新ViewPager中的WebView

时间:2015-04-01 14:20:54

标签: android webview android-asynctask android-viewpager

WebView内有ViewPager。当WebView开始加载数据时,它需要对某些URL执行任务,从这些URL获取一些ID,然后更新视图。

我的问题是,如何使用最新内容更新WebView内的ViewPagerViewPager位于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;
            }

        }

    }

如果在onPostExecute()完成asynctask后,如何设置webview加载数据?

1 个答案:

答案 0 :(得分:0)

我会在你的异步任务中创建一个接口(也许可以将它拆分成自己的类),例如下面的那个;

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

然后让你的Activity实现这个接口(以及相应的方法),即

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

            }

然后在你的适配器设置中添加一个带有html字符串的实例变量的方法,该字符串在你的instantiateItem()方法中使用,并在适配器上调用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

      }
}

希望这有帮助! : - )