add headlines flavor images

This commit is contained in:
Andrew Dolgov 2014-10-16 01:21:49 +04:00
parent a77d00eeea
commit 8da85b9157
7 changed files with 262 additions and 129 deletions

Binary file not shown.

View File

@ -74,6 +74,24 @@
android:textSize="12sp" />
</LinearLayout>
<FrameLayout
android:paddingTop="3dp"
android:id="@+id/flavorImageHolder"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/flavor_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="128dp"
android:scaleType="centerInside"
android:src="@null"
android:visibility="gone" />
</FrameLayout>
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
@ -83,14 +101,7 @@
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineExcerptTextColor"
android:textSize="13sp" />
<WebView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="3dp"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -72,6 +72,24 @@
android:textSize="12sp" />
</LinearLayout>
<FrameLayout
android:paddingTop="3dp"
android:id="@+id/flavorImageHolder"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/flavor_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="128dp"
android:scaleType="centerInside"
android:src="@null"
android:visibility="gone" />
</FrameLayout>
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
@ -81,13 +99,6 @@
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineSelectedExcerptTextColor"
android:textSize="13sp" />
<WebView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="3dp"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"

View File

@ -73,6 +73,24 @@
android:textSize="12sp" />
</LinearLayout>
<FrameLayout
android:paddingTop="3dp"
android:id="@+id/flavorImageHolder"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/flavor_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="128dp"
android:scaleType="centerInside"
android:src="@null"
android:visibility="gone" />
</FrameLayout>
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
@ -82,13 +100,6 @@
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineSelectedExcerptTextColor"
android:textSize="13sp" />
<WebView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="3dp"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"

View File

@ -14,7 +14,10 @@
android:layout_height="match_parent"
android:background="?headlineUnreadBackground"
android:orientation="vertical"
android:paddingTop="6dp" android:paddingLeft="6dp" android:paddingRight="6dp" android:paddingBottom="2dp" > >
android:paddingBottom="2dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="6dp" >
<LinearLayout
android:id="@+id/linearLayout6"
@ -51,16 +54,16 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:singleLine="true"
android:fontFamily="sans-serif-light"
android:text="Example Feed"
android:text="Example Feed"
android:textColor="?headlineSecondaryTextColor"
android:textSize="12sp" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="sans-serif-light"
@ -70,23 +73,34 @@
android:textSize="12sp" />
</LinearLayout>
<FrameLayout
android:paddingTop="3dp"
android:id="@+id/flavorImageHolder"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/flavor_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="128dp"
android:scaleType="centerInside"
android:src="@null"
android:visibility="gone" />
</FrameLayout>
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="3dp"
android:lineSpacingExtra="2sp"
android:paddingTop="3dp"
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineExcerptTextColor"
android:textSize="13sp" />
<WebView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="3dp"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -95,7 +109,7 @@
<CheckBox
android:id="@+id/selected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:focusable="false" />
@ -105,30 +119,30 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:singleLine="true"
android:text="by Author"
android:fontFamily="sans-serif-light"
android:textStyle="italic"
android:textColor="?headlineSecondaryTextColor"
android:textSize="12sp" />
android:textSize="12sp"
android:textStyle="italic" />
<ImageView
android:id="@+id/marked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_weight="0"
android:clickable="true"
android:layout_marginRight="8dp"
android:src="@drawable/ic_star_empty" />
<ImageView
android:id="@+id/published"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dp"
android:layout_weight="0"
android:clickable="true"
android:layout_marginRight="6dp"
android:src="@drawable/ic_unpublished" />
<ImageView

View File

@ -1,13 +1,21 @@
package org.fox.ttrss;
import java.io.File;
import java.io.IOException;
import org.fox.ttrss.util.DatabaseHelper;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.utils.StorageUtils;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.net.http.HttpResponseCache;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.widget.SwipeRefreshLayout;
@ -44,6 +52,19 @@ public class CommonActivity extends ActionBarActivity {
protected SharedPreferences m_prefs;
/* protected void enableHttpCaching() {
// enable resource caching
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
try {
File httpCacheDir = new File(getApplicationContext().getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
} catch (IOException e) {
e.printStackTrace();
}
}
} */
protected void setSmallScreen(boolean smallScreen) {
Log.d(TAG, "m_smallScreenMode=" + smallScreen);
m_smallScreenMode = smallScreen;
@ -128,11 +149,14 @@ public class CommonActivity extends ActionBarActivity {
}
initDatabase();
m_compatMode = android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB;
Log.d(TAG, "m_compatMode=" + m_compatMode);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).build();
ImageLoader.getInstance().init(config);
super.onCreate(savedInstanceState);
}
@ -225,5 +249,4 @@ public class CommonActivity extends ActionBarActivity {
return display.getWidth();
}
}
}

View File

@ -1,5 +1,10 @@
package org.fox.ttrss;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
@ -24,10 +29,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.net.Uri;
import android.net.http.HttpResponseCache;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
@ -57,6 +66,10 @@ import android.widget.ListView;
import android.widget.TextView;
import com.google.gson.JsonElement;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
public class HeadlinesFragment extends Fragment implements OnItemClickListener, OnScrollListener {
public static enum ArticlesSelection { ALL, NONE, UNREAD };
@ -781,98 +794,92 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
});
}
TextView te = (TextView)v.findViewById(R.id.excerpt);
String articleContent = article.content != null ? article.content : "";
/* if (m_prefs.getBoolean("headlines_full_content", false)) {
final WebView content = (WebView)v.findViewById(R.id.content);
if (content != null) {
Document doc = Jsoup.parse(articleContent);
if (doc != null) {
// thanks webview for crashing on <video> tag
Elements videos = doc.select("video");
for (Element video : videos)
video.remove();
articleContent = doc.toString();
}
content.setVisibility(View.VISIBLE);
if (te != null) te.setVisibility(View.GONE);
String baseUrl = null;
try {
URL url = new URL(article.link);
baseUrl = url.getProtocol() + "://" + url.getHost();
} catch (MalformedURLException e) {
//
}
TypedValue tv = new TypedValue();
getActivity().getTheme().resolveAttribute(R.attr.linkColor, tv, true);
String cssOverride = "";
String theme = m_prefs.getString("theme", CommonActivity.THEME_DEFAULT);
if (CommonActivity.THEME_HOLO.equals(theme)) {
cssOverride = "body { background : transparent; color : #e0e0e0}";
} else if (CommonActivity.THEME_DARK.equals(theme)) {
cssOverride = "body { background : transparent; color : #e0e0e0}";
} else {
cssOverride = "body { background : transparent; }";
}
content.setBackgroundColor(Color.TRANSPARENT);
String hexColor = String.format("#%06X", (0xFFFFFF & tv.data));
if (m_prefs.getBoolean("justify_article_text", true)) {
cssOverride += "body { text-align : justify; } ";
}
articleContent = "<html>" +
"<head>" +
"<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">" +
"<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\" />" +
"<style type=\"text/css\">" +
"body { padding : 0px; margin : 0px; line-height : 130%; }" +
cssOverride +
"img { max-width : 100%; max-height : "+m_maxImageSize+"px; width : auto; height : auto; }" +
"table { width : 100%; }" +
"a:link {color: "+hexColor+";} a:visited { color: "+hexColor+";}" +
"</style>" +
"</head>" +
"<body>" + articleContent + "</body></html>";
WebSettings ws = content.getSettings();
ws.setSupportZoom(false);
ws.setDefaultFontSize(headlineFontSize);
TextView te = (TextView)v.findViewById(R.id.excerpt);
content.loadDataWithBaseURL(baseUrl, articleContent, "text/html", "utf-8", null);
}
if (te != null) {
if (!m_prefs.getBoolean("headlines_show_content", true)) {
te.setVisibility(View.GONE);
} else {
String excerpt = Jsoup.parse(articleContent).text();
} else { */
if (te != null) {
if (!m_prefs.getBoolean("headlines_show_content", true)) {
te.setVisibility(View.GONE);
} else {
String excerpt = Jsoup.parse(articleContent).text();
if (excerpt.length() > CommonActivity.EXCERPT_MAX_SIZE)
excerpt = excerpt.substring(0, CommonActivity.EXCERPT_MAX_SIZE) + "...";
te.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineFontSize);
te.setText(excerpt);
}
if (excerpt.length() > CommonActivity.EXCERPT_MAX_SIZE)
excerpt = excerpt.substring(0, CommonActivity.EXCERPT_MAX_SIZE) + "...";
te.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineFontSize);
te.setText(excerpt);
}
// }
}
final ImageView flavorImage = (ImageView) v.findViewById(R.id.flavor_image);
if (flavorImage != null && m_prefs.getBoolean("headlines_show_content", true)) {
flavorImage.setVisibility(View.GONE);
Document doc = Jsoup.parse(articleContent);
if (doc != null) {
Element img = doc.select("img").first();
if (img != null) {
URL imgUri;
try {
imgUri = new URL(img.attr("src"));
flavorImage.setTag(imgUri);
DisplayImageOptions options = new DisplayImageOptions.Builder().
cacheInMemory(true).
cacheOnDisk(true).
build();
ImageLoader.getInstance().displayImage(imgUri.toString(), flavorImage, options, new ImageLoadingListener() {
@Override
public void onLoadingCancelled(String arg0,
View arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingComplete(String arg0,
View arg1, Bitmap arg2) {
// TODO Auto-generated method stub
flavorImage.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String arg0,
View arg1, FailReason arg2) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingStarted(String arg0,
View arg1) {
// TODO Auto-generated method stub
}
});
//new DownloadFlavorImagesTask().execute(flavorImage);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
String articleAuthor = article.author != null ? article.author : "";
@ -1081,5 +1088,61 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public Feed getFeed() {
return m_feed;
}
/* class DownloadFlavorImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
@Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download((URL)imageView.getTag());
}
@Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
imageView.setImageBitmap(result);
imageView.setVisibility(View.VISIBLE);
}
}
private Bitmap download(URL url) {
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setUseCaches(true);
conn.connect();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[256];
int read = 0;
while ((read = conn.getInputStream().read(buf)) >= 0) {
bos.write(buf, 0, read);
}
final BitmapFactory.Options options = new BitmapFactory.Options();
byte[] bitmap = bos.toByteArray();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, options);
options.inJustDecodeBounds = false;
int inSampleSize = CommonActivity.calculateInSampleSize(options, 128, 128);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, options);
return decodedBitmap;
} catch (OutOfMemoryError e) {
Log.d(TAG, "OOM while trying to decode headline flavor image. :(");
e.printStackTrace();
} catch (IOException e) {
//
}
return null;
}
} */
}