我WebView
内有ViewPager
。当WebView
开始加载数据时,它需要对某些URL执行任务,从这些URL获取一些ID,然后更新视图。
我的问题是,如何使用最新内容更新WebView
内的ViewPager
? 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("%", "%");
// 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加载数据?
答案 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
}
}
希望这有帮助! : - )