Browse Source

Custom Bottom bar with page navigation. FAB for post action etc. Expandable cards show/hide post's date and number. Parsed necessary data for post focusing.

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
a56dcac9f7
  1. 1
      app/build.gradle
  2. 398
      app/src/main/java/gr/thmmy/mthmmy/activities/TopicActivity.java
  3. 12
      app/src/main/java/gr/thmmy/mthmmy/data/Post.java
  4. 9
      app/src/main/res/drawable/ic_add_fab.xml
  5. 8
      app/src/main/res/drawable/page_first.xml
  6. 8
      app/src/main/res/drawable/page_last.xml
  7. 8
      app/src/main/res/drawable/page_next.xml
  8. 8
      app/src/main/res/drawable/page_previous.xml
  9. 75
      app/src/main/res/layout/activity_topic.xml
  10. 78
      app/src/main/res/layout/activity_topic_post_row.xml
  11. 14
      app/src/main/res/layout/topic_page_select.xml
  12. 23
      app/src/main/res/values/colors.xml
  13. 1
      app/src/main/res/values/dimens.xml
  14. 5
      app/src/main/res/values/strings.xml

1
app/build.gradle

@ -5,6 +5,7 @@ android {
buildToolsVersion "25.0.0" buildToolsVersion "25.0.0"
defaultConfig { defaultConfig {
vectorDrawables.useSupportLibrary = true
applicationId "gr.thmmy.mthmmy" applicationId "gr.thmmy.mthmmy"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 25 targetSdkVersion 25

398
app/src/main/java/gr/thmmy/mthmmy/activities/TopicActivity.java

@ -1,19 +1,25 @@
package gr.thmmy.mthmmy.activities; package gr.thmmy.mthmmy.activities;
import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.widget.CardView;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.EditorInfo; import android.webkit.WebResourceRequest;
import android.webkit.WebView; import android.webkit.WebView;
import android.widget.EditText; import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@ -28,6 +34,7 @@ import org.jsoup.select.Elements;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLHandshakeException;
@ -42,16 +49,27 @@ public class TopicActivity extends BaseActivity {
//-----------------------------------------CLASS VARIABLES------------------------------------------ //-----------------------------------------CLASS VARIABLES------------------------------------------
/* --Post-- */ /* --Posts-- */
private List<Post> postsList; private List<Post> postsList;
private LinearLayout postsLinearLayout; private LinearLayout postsLinearLayout;
/* --Topic's page-- */ private static final int NO_POST_FOCUS = -1;
private int postFocus = NO_POST_FOCUS;
/* --Posts end-- */
/* --Topic's pages-- */
private int thisPage = 1; private int thisPage = 1;
private String base_url = ""; private String base_url = "";
private int numberOfPages = 1; private int numberOfPages = 1;
private EditText pageSelect;
private final SparseArray<String> pagesUrls = new SparseArray<>(); private final SparseArray<String> pagesUrls = new SparseArray<>();
/* --Topic's page end-- */ //Page select
private TextView pageIndicator;
private final Handler repeatUpdateHandler = new Handler();
private final long INITIAL_DELAY = 500;
private boolean autoIncrement = false;
private boolean autoDecrement = false;
private static final int SMALL_STEP = 1;
private static final int LARGE_STEP = 10;
private Integer pageValue;
/* --Topic's pages end-- */
/* --Thumbnail-- */ /* --Thumbnail-- */
private static final int THUMBNAIL_SIZE = 80; private static final int THUMBNAIL_SIZE = 80;
private ImageLoader imageLoader = ImageController.getInstance().getImageLoader(); private ImageLoader imageLoader = ImageController.getInstance().getImageLoader();
@ -60,8 +78,9 @@ public class TopicActivity extends BaseActivity {
//Other variables //Other variables
private ProgressBar progressBar; private ProgressBar progressBar;
private static final String TAG = "TopicActivity"; private static final String TAG = "TopicActivity";
private String topicTitle;
private String parsedTitle;
private ActionBar actionbar;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -69,7 +88,7 @@ public class TopicActivity extends BaseActivity {
setContentView(R.layout.activity_topic); setContentView(R.layout.activity_topic);
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
final String topicTitle = getIntent().getExtras().getString("TOPIC_TITLE"); topicTitle = getIntent().getExtras().getString("TOPIC_TITLE");
//Variables initialization //Variables initialization
postsLinearLayout = (LinearLayout) findViewById(R.id.posts_list); postsLinearLayout = (LinearLayout) findViewById(R.id.posts_list);
@ -81,47 +100,22 @@ public class TopicActivity extends BaseActivity {
postsList = new ArrayList<>(); postsList = new ArrayList<>();
ActionBar actionbar = getSupportActionBar(); actionbar = getSupportActionBar();
if (actionbar != null) if (actionbar != null)
actionbar.setTitle(topicTitle); if(!Objects.equals(topicTitle, ""))
actionbar.setTitle(topicTitle);
/* Add page select field to the Action Bar */
//Edit Action Bar's parameters
ActionBar.LayoutParams lp = new ActionBar.LayoutParams( ImageButton firstPage = (ImageButton) findViewById(R.id.page_first_button);
LinearLayout.LayoutParams.WRAP_CONTENT ImageButton previousPage = (ImageButton) findViewById(R.id.page_previous_button);
, LinearLayout.LayoutParams.WRAP_CONTENT pageIndicator = (TextView) findViewById(R.id.page_indicator);
, Gravity.END | Gravity.CENTER_VERTICAL); ImageButton nextPage = (ImageButton) findViewById(R.id.page_next_button);
//Initialize layout to be added ImageButton lastPage = (ImageButton) findViewById(R.id.page_last_button);
View customNav = LayoutInflater.from(this).inflate(R.layout.topic_page_select, null);
//Initialize text field initDecrementButton(firstPage, LARGE_STEP);
pageSelect = (EditText) customNav.findViewById(R.id.select_page); initDecrementButton(previousPage, SMALL_STEP);
pageSelect.setOnEditorActionListener(new TextView.OnEditorActionListener() { initIncrementButton(nextPage, SMALL_STEP);
@Override initIncrementButton(lastPage, LARGE_STEP);
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { //When page is changed
if (actionId == EditorInfo.IME_ACTION_GO) {
//Get page requested by user
int pageRequested = Integer.parseInt(pageSelect.getText().toString());
if (pageRequested == thisPage) {
Toast.makeText(getBaseContext()
, "You already are here!", Toast.LENGTH_LONG).show();
} else if (pageRequested >= 1 && pageRequested <= numberOfPages) {
//Restart activity with new page
Intent intent = getIntent();
intent.putExtra("TOPIC_URL", pagesUrls.get(pageRequested - 1));
intent.putExtra("TOPIC_TITLE", topicTitle);
finish();
startActivity(intent);
} else { //Invalid page request
Toast.makeText(getBaseContext()
, "There is no such page!", Toast.LENGTH_LONG).show();
}
}
return true;
}
});
assert actionbar != null;
actionbar.setCustomView(customNav, lp); //Add feature to Action Bar
actionbar.setDisplayShowCustomEnabled(true);
new TopicTask().execute(extras.getString("TOPIC_URL")); //Attempt data parsing new TopicTask().execute(extras.getString("TOPIC_URL")); //Attempt data parsing
} }
@ -132,6 +126,105 @@ public class TopicActivity extends BaseActivity {
ImageController.getInstance().cancelPendingRequests(); ImageController.getInstance().cancelPendingRequests();
} }
private void initIncrementButton(ImageButton increment, final int step){
// Increment once for a click
increment.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
increment(step);
changePage(pageValue - 1);
}
});
// Auto increment for a long click
increment.setOnLongClickListener(
new View.OnLongClickListener(){
public boolean onLongClick(View arg0) {
autoIncrement = true;
repeatUpdateHandler.postDelayed(new RepetetiveUpdater(step), INITIAL_DELAY);
return false;
}
}
);
// When the button is released, if we're auto incrementing, stop
increment.setOnTouchListener( new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if( event.getAction() == MotionEvent.ACTION_UP && autoIncrement ){
autoIncrement = false;
changePage(pageValue - 1);
}
return false;
}
});
}
private void initDecrementButton(ImageButton decrement, final int step){
// Decrement once for a click
decrement.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
decrement(step);
changePage(pageValue - 1);
}
});
// Auto Decrement for a long click
decrement.setOnLongClickListener(
new View.OnLongClickListener(){
public boolean onLongClick(View arg0) {
autoDecrement = true;
repeatUpdateHandler.postDelayed( new RepetetiveUpdater(step), INITIAL_DELAY);
return false;
}
}
);
// When the button is released, if we're auto decrementing, stop
decrement.setOnTouchListener( new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if( event.getAction() == MotionEvent.ACTION_UP && autoDecrement ){
autoDecrement = false;
changePage(pageValue - 1);
}
return true;
}
});
}
private void increment(int step){
if( pageValue < numberOfPages - step - 1){
pageValue = pageValue + step;
}
pageIndicator.setText(pageValue + "/" + String.valueOf(numberOfPages));
if(pageValue >= 1000)
pageIndicator.setTextSize(16);
else
pageIndicator.setTextSize(20);
}
private void decrement(int step){
if( pageValue > step + 1 ){
pageValue = pageValue - step;
}
pageIndicator.setText(pageValue + "/" + String.valueOf(numberOfPages));
if(numberOfPages >= 1000)
pageIndicator.setTextSize(16);
else
pageIndicator.setTextSize(20);
}
private void changePage(int pageRequested){
if(pageRequested != thisPage - 1) {
//Restart activity with new page
Intent intent = getIntent();
intent.putExtra("TOPIC_URL", pagesUrls.get(pageRequested));
intent.putExtra("TOPIC_TITLE", topicTitle);
finish();
startActivity(intent);
}
}
//---------------------------------------TOPIC ASYNC TASK------------------------------------------- //---------------------------------------TOPIC ASYNC TASK-------------------------------------------
public class TopicTask extends AsyncTask<String, Void, Boolean> { public class TopicTask extends AsyncTask<String, Void, Boolean> {
//Class variables //Class variables
@ -145,10 +238,18 @@ public class TopicActivity extends BaseActivity {
protected Boolean doInBackground(String... strings) { protected Boolean doInBackground(String... strings) {
Document document; Document document;
base_url = strings[0].substring(0, strings[0].lastIndexOf(".")); //This topic's base url base_url = strings[0].substring(0, strings[0].lastIndexOf(".")); //This topic's base url
String pageLink = strings[0]; //This page's url String pageUrl = strings[0]; //This page's url
//Find message focus if present
{
if(pageUrl.contains("msg")){
String tmp = pageUrl.substring(pageUrl.indexOf("msg") + 3);
postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf(";")));
}
}
Request request = new Request.Builder() Request request = new Request.Builder()
.url(pageLink) .url(pageUrl)
.build(); .build();
try { try {
Response response = client.newCall(request).execute(); Response response = client.newCall(request).execute();
@ -174,11 +275,26 @@ public class TopicActivity extends BaseActivity {
progressBar.setVisibility(ProgressBar.INVISIBLE); //Hide progress bar progressBar.setVisibility(ProgressBar.INVISIBLE); //Hide progress bar
populateLayout(); //Show parsed data populateLayout(); //Show parsed data
//Set current page //Set current page
pageSelect.setHint(String.valueOf(thisPage) + "/" + String.valueOf(numberOfPages)); pageIndicator.setText(String.valueOf(thisPage) + "/" + String.valueOf(numberOfPages));
pageValue = thisPage;
if(numberOfPages >= 1000)
pageIndicator.setTextSize(16);
} }
/* Parse method */ /* Parse method */
private void parse(Document document) { private void parse(Document document) {
//Method's variables
final int NO_INDEX = -1;
//Find topic title if missing
if(topicTitle == null || Objects.equals(topicTitle, "")){
parsedTitle = document.select("td[id=top_subject]").first().text();
Log.d(TAG, parsedTitle);
parsedTitle = parsedTitle.substring(parsedTitle.indexOf("Topic:") + 7
, parsedTitle.indexOf("(Read") - 8);
Log.d(TAG, parsedTitle);
}
{ //Find current page's index { //Find current page's index
Elements findCurrentPage = document.select("td:contains(Pages:)>b"); //Contains pages Elements findCurrentPage = document.select("td:contains(Pages:)>b"); //Contains pages
for (Element item : findCurrentPage) { for (Element item : findCurrentPage) {
@ -209,8 +325,8 @@ public class TopicActivity extends BaseActivity {
for (Element item : rows) { //For every post for (Element item : rows) { //For every post
//Variables to pass //Variables to pass
String p_userName, p_thumbnailUrl, p_subject, p_post; String p_userName, p_thumbnailUrl, p_subject, p_post, p_postDate;
int p_postNum; int p_postNum, p_postIndex;
//Find the Username //Find the Username
Element userName = item.select("a[title^=View the profile of]").first(); Element userName = item.select("a[title^=View the profile of]").first();
@ -238,7 +354,13 @@ public class TopicActivity extends BaseActivity {
p_post = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />" p_post = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />"
+ p_post); //style.css + p_post); //style.css
//Find post's index number //Find post's submit date
Element postDate = item.select("div.smalltext:matches(on:)").first();
p_postDate = postDate.text();
p_postDate = p_postDate.substring(p_postDate.indexOf("on:") + 4
,p_postDate.indexOf(" »"));
//Find post's number
Element postNum = item.select("div.smalltext:matches(Reply #)").first(); Element postNum = item.select("div.smalltext:matches(Reply #)").first();
if (postNum == null) { //Topic starter if (postNum == null) { //Topic starter
p_postNum = 0; p_postNum = 0;
@ -247,16 +369,34 @@ public class TopicActivity extends BaseActivity {
p_postNum = Integer.parseInt(tmp_str.substring(0, tmp_str.indexOf(" on"))); p_postNum = Integer.parseInt(tmp_str.substring(0, tmp_str.indexOf(" on")));
} }
//Find post's index
Element postIndex = item.select("a[name^=msg]").first();
if(postIndex == null)
p_postIndex = NO_INDEX;
else {
String tmp = postIndex.attr("name");
p_postIndex = Integer.parseInt(tmp.substring(tmp.indexOf("msg") + 3));
}
//Add new post in postsList //Add new post in postsList
postsList.add(new Post(p_thumbnailUrl, p_userName, p_subject postsList.add(new Post(p_thumbnailUrl, p_userName, p_subject
, p_post, p_postNum)); , p_post, p_postDate, p_postNum, p_postIndex));
} }
} }
/* Parse method end */ /* Parse method end */
} }
//-------------------------------------TOPIC ASYNC TASK END----------------------------------------- //-------------------------------------TOPIC ASYNC TASK END-----------------------------------------
//----------------------------------------POPULATE UI METHOD----------------------------------------
private void populateLayout() { //Show parsed data private void populateLayout() { //Show parsed data
//Set topic title if not already present
if (topicTitle == null || Objects.equals(topicTitle, "")) {
topicTitle = parsedTitle;
if (actionbar != null){
actionbar.setTitle(topicTitle);
}
}
//Initialize an inflater //Initialize an inflater
LayoutInflater inflater = (LayoutInflater) getApplicationContext() LayoutInflater inflater = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@ -270,11 +410,18 @@ public class TopicActivity extends BaseActivity {
imageLoader = ImageController.getInstance().getImageLoader(); imageLoader = ImageController.getInstance().getImageLoader();
//Initialize layout's graphic elements //Initialize layout's graphic elements
final FrameLayout cardExpandable = (FrameLayout) convertView.findViewById(R.id.card_expandable);
TextView postDate = (TextView) convertView.findViewById(R.id.post_date);
TextView postNum = (TextView) convertView.findViewById(R.id.post_number);
CircularNetworkImageView thumbnail = (CircularNetworkImageView) convertView.findViewById(R.id.thumbnail); CircularNetworkImageView thumbnail = (CircularNetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView username = (TextView) convertView.findViewById(R.id.username); TextView username = (TextView) convertView.findViewById(R.id.username);
TextView postNum = (TextView) convertView.findViewById(R.id.post_number);
TextView subject = (TextView) convertView.findViewById(R.id.subject); TextView subject = (TextView) convertView.findViewById(R.id.subject);
WebView post = (WebView) convertView.findViewById(R.id.post); WebView post = (WebView) convertView.findViewById(R.id.post);
CardView cardView = (CardView) convertView.findViewById(R.id.card_view);
//Post's WebView parameters set
post.setClickable(true);
post.setWebViewClient(new LinkLauncher());
//Avoiding errors about layout having 0 width/height //Avoiding errors about layout having 0 width/height
thumbnail.setMinimumWidth(1); thumbnail.setMinimumWidth(1);
@ -291,6 +438,9 @@ public class TopicActivity extends BaseActivity {
//Username set //Username set
username.setText(item.getAuthor()); username.setText(item.getAuthor());
//Post's submit date set
postDate.setText(item.getPostDate());
//Post's index number set //Post's index number set
if (item.getPostNumber() != 0) if (item.getPostNumber() != 0)
postNum.setText("#" + item.getPostNumber()); postNum.setText("#" + item.getPostNumber());
@ -300,10 +450,138 @@ public class TopicActivity extends BaseActivity {
//Post's text set //Post's text set
post.loadDataWithBaseURL("file:///android_asset/", item.getContent(), "text/html", "UTF-8", null); post.loadDataWithBaseURL("file:///android_asset/", item.getContent(), "text/html", "UTF-8", null);
post.setEnabled(false);
/* --"Card expand/collapse"-like functionality-- */
if (item.getPostNumber() != 0) {
//Should expand/collapse when card is touched
cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cardExpandable.getVisibility() == View.GONE)
cardExpandable.setVisibility(View.VISIBLE);
else
cardExpandable.setVisibility(View.GONE);
}
});
//Also when post is clicked
post.setOnTouchListener(new View.OnTouchListener() {
final static int FINGER_RELEASED = 0;
final static int FINGER_TOUCHED = 1;
final static int FINGER_DRAGGING = 2;
final static int FINGER_UNDEFINED = 3;
private int fingerState = FINGER_RELEASED;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (fingerState == FINGER_RELEASED)
fingerState = FINGER_TOUCHED;
else
fingerState = FINGER_UNDEFINED;
break;
case MotionEvent.ACTION_UP:
fingerState = FINGER_RELEASED;
if (cardExpandable.getVisibility() == View.GONE)
cardExpandable.setVisibility(View.VISIBLE);
else
cardExpandable.setVisibility(View.GONE);
break;
case MotionEvent.ACTION_MOVE:
if (fingerState == FINGER_TOUCHED || fingerState == FINGER_DRAGGING) fingerState = FINGER_DRAGGING;
else fingerState = FINGER_UNDEFINED;
break;
default:
fingerState = FINGER_UNDEFINED;
}
return false;
}
});
}
/* --"Card expand/collapse"-like functionality end-- */
//Add view to the linear layout that holds all posts //Add view to the linear layout that holds all posts
postsLinearLayout.addView(convertView); postsLinearLayout.addView(convertView);
//Set post focus
if(postFocus != NO_POST_FOCUS){
if(item.getPostIndex() == postFocus){
//TODO
}
}
}
}
//--------------------------------------POPULATE UI METHOD END--------------------------------------
//--------------------------------------CUSTOM WEBVIEW CLIENT---------------------------------------
private class LinkLauncher extends WebViewClient {
//Older versions
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
final Uri uri = Uri.parse(url);
return handleUri(uri);
}
//Newest versions
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
final Uri uri = request.getUrl();
return handleUri(uri);
}
//Handle url clicks
private boolean handleUri(final Uri uri) {
//Method always returns true as we don't want any url to be loaded in WebViews
Log.i(TAG, "Uri =" + uri);
final String host = uri.getHost(); //Get requested url's host
//Determine if you are going to pass the url to a
//host's application activity or load it in a browser.
if (Objects.equals(host, "www.thmmy.gr")) {
//This is my web site, so figure out what Activity should launch
if (uri.toString().contains("topic=")) {
//Restart activity with new topic
Intent intent = getIntent();
intent.putExtra("TOPIC_URL", uri.toString());
intent.putExtra("TOPIC_TITLE", "");
finish();
startActivity(intent);
}
return true;
}
//Otherwise, the link is not for a page on my site, so launch
//another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
return true;
}
}
//------------------------------------CUSTOM WEBVIEW CLIENT END-------------------------------------
class RepetetiveUpdater implements Runnable {
private final int step;
RepetetiveUpdater(int step){this.step = step;}
public void run() {
long REPEAT_DELAY = 250;
if( autoIncrement ){
increment(step);
repeatUpdateHandler.postDelayed( new RepetetiveUpdater(step), REPEAT_DELAY);
} else if( autoDecrement ){
decrement(step);
repeatUpdateHandler.postDelayed( new RepetetiveUpdater(step), REPEAT_DELAY);
}
} }
} }
} }

12
app/src/main/java/gr/thmmy/mthmmy/data/Post.java

@ -5,14 +5,18 @@ public class Post {
private final String author; private final String author;
private final String subject; private final String subject;
private final String content; private final String content;
private final String postDate;
private final int postNumber; private final int postNumber;
private final int postIndex;
public Post(String thumbnailUrl, String author, String subject, String content, int postNumber) { public Post(String thumbnailUrl, String author, String subject, String content, String postDate, int postNumber, int postIndex) {
this.thumbnailUrl = thumbnailUrl; this.thumbnailUrl = thumbnailUrl;
this.author = author; this.author = author;
this.subject = subject; this.subject = subject;
this.content = content; this.content = content;
this.postDate = postDate;
this.postNumber = postNumber; this.postNumber = postNumber;
this.postIndex = postIndex;
} }
public String getThumbnailUrl() { public String getThumbnailUrl() {
@ -31,7 +35,13 @@ public class Post {
return subject; return subject;
} }
public String getPostDate() { return postDate;}
public int getPostNumber() { public int getPostNumber() {
return postNumber; return postNumber;
} }
public int getPostIndex() {
return postIndex;
}
} }

9
app/src/main/res/drawable/ic_add_fab.xml

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFF"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

8
app/src/main/res/drawable/page_first.xml

@ -0,0 +1,8 @@
<!-- drawable/page_first.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path android:fillColor="#FFF" android:pathData="M18.41,16.59L13.82,12L18.41,7.41L17,6L11,12L17,18L18.41,16.59M6,6H8V18H6V6Z" />
</vector>

8
app/src/main/res/drawable/page_last.xml

@ -0,0 +1,8 @@
<!-- drawable/page_last.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path android:fillColor="#FFF" android:pathData="M5.59,7.41L10.18,12L5.59,16.59L7,18L13,12L7,6L5.59,7.41M16,6H18V18H16V6Z" />
</vector>

8
app/src/main/res/drawable/page_next.xml

@ -0,0 +1,8 @@
<!-- drawable/page_next.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path android:fillColor="#FFF" android:pathData="M16,18H18V6H16M6,18L14.5,12L6,6V18Z" />
</vector>

8
app/src/main/res/drawable/page_previous.xml

@ -0,0 +1,8 @@
<!-- drawable/page_previous.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path android:fillColor="#FFF" android:pathData="M6,18V6H8V18H6M9.5,12L18,6V18L9.5,12Z" />
</vector>

75
app/src/main/res/layout/activity_topic.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -10,6 +11,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginBottom="50dp"
android:scrollbars="none" android:scrollbars="none"
tools:context="gr.thmmy.mthmmy.activities.TopicActivity"> tools:context="gr.thmmy.mthmmy.activities.TopicActivity">
@ -25,6 +27,79 @@
</ScrollView> </ScrollView>
<FrameLayout
android:id="@+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginTop="-2dp"
android:elevation="8dp"
android:outlineProvider="bounds">
<LinearLayout
android:id="@+id/bottom_navigation_bar_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primary_dark"
android:orientation="horizontal">
<ImageButton
android:id="@+id/page_first_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@string/text_first"
app:srcCompat="@drawable/page_first"/>
<ImageButton
android:id="@+id/page_previous_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@string/text_previous"
app:srcCompat="@drawable/page_previous"/>
<TextView
android:id="@+id/page_indicator"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:textColor="@color/white"
android:gravity="center"
android:hint="@string/text_page"
android:maxLines="1"
android:textSize="20sp"/>
<ImageButton
android:id="@+id/page_next_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@string/text_next"
app:srcCompat="@drawable/page_next"/>
<ImageButton
android:id="@+id/page_last_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@string/text_last"
app:srcCompat="@drawable/page_last"/>
<Space
android:layout_width="80dp"
android:layout_height="match_parent"/>
</LinearLayout>
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:elevation="12dp"
app:srcCompat="@drawable/ic_add_fab"/>
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
android:layout_width="wrap_content" android:layout_width="wrap_content"

78
app/src/main/res/layout/activity_topic_post_row.xml

@ -1,11 +1,46 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:animateLayoutChanges="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:paddingEnd="4dp" android:paddingEnd="4dp"
android:paddingStart="4dp"> android:paddingStart="4dp">
<FrameLayout
android:animateLayoutChanges="true"
android:id="@+id/card_expandable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:visibility="gone">
<TextView
android:id="@+id/post_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:paddingEnd="5dp"
android:paddingStart="5dp"
android:text=""
android:textColor="@color/card_expand_text_color"
android:textSize="12sp"
/>
<TextView
android:id="@+id/post_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:paddingEnd="5dp"
android:paddingStart="5dp"
android:text=""
android:textColor="@color/card_expand_text_color"
android:textSize="12sp"
/>
</FrameLayout>
<android.support.v7.widget.CardView <android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view" android:id="@+id/card_view"
@ -20,25 +55,22 @@
card_view:cardUseCompatPadding="true"> card_view:cardUseCompatPadding="true">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical">
android:padding="5dp">
<RelativeLayout <RelativeLayout
android:id="@+id/header" android:id="@+id/header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:padding="16dp">
<FrameLayout <FrameLayout
android:id="@+id/thumbnail_holder" android:id="@+id/thumbnail_holder"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_centerVertical="true" android:layout_centerVertical="true">
android:layout_marginBottom="3dp"
android:layout_marginEnd="3dp"
android:layout_marginTop="3dp">
<gr.thmmy.mthmmy.utils.CircularNetworkImageView <gr.thmmy.mthmmy.utils.CircularNetworkImageView
android:id="@+id/thumbnail" android:id="@+id/thumbnail"
@ -46,9 +78,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:adjustViewBounds="false" android:adjustViewBounds="false"
android:maxHeight="@dimen/thumbnail_size" android:maxHeight="@dimen/thumbnail_size"
android:maxWidth="@dimen/thumbnail_size" android:maxWidth="@dimen/thumbnail_size"/>
android:paddingEnd="2dp"
android:paddingStart="2dp"/>
</FrameLayout> </FrameLayout>
<TextView <TextView
@ -57,6 +87,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
android:layout_marginStart="16dp"
android:layout_toEndOf="@+id/thumbnail_holder" android:layout_toEndOf="@+id/thumbnail_holder"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
@ -64,20 +95,15 @@
android:textColor="@color/black" android:textColor="@color/black"
android:textStyle="bold"/> android:textStyle="bold"/>
<TextView
android:id="@+id/post_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:text=""/>
<TextView <TextView
android:id="@+id/subject" android:id="@+id/subject"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/username" android:layout_below="@+id/username"
android:layout_marginStart="16dp"
android:layout_toEndOf="@+id/thumbnail_holder" android:layout_toEndOf="@+id/thumbnail_holder"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/subject" android:text="@string/subject"
/> />
@ -88,27 +114,27 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginBottom="9dp" android:layout_marginBottom="9dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="16dp"
android:layout_marginRight="8dp" android:layout_marginRight="16dp"
android:layout_marginTop="3dp"
android:background="@color/divider"/> android:background="@color/divider"/>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:layout_marginBottom="16dp">
<WebView <WebView
android:id="@+id/post" android:id="@+id/post"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginLeft="8dp" android:layout_marginLeft="16dp"
android:layout_marginRight="8dp" android:layout_marginRight="16dp"
android:background="@color/white" android:background="@color/white"
android:clickable="true"
android:text="@string/post" android:text="@string/post"
/> />
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </android.support.v7.widget.CardView>
</LinearLayout> </LinearLayout>

14
app/src/main/res/layout/topic_page_select.xml

@ -1,14 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:id="@+id/select_page"
android:layout_width="50dp"
android:layout_height="match_parent"
android:imeOptions="actionGo"
android:inputType="number|textNoSuggestions"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="20sp"/>
</LinearLayout>

23
app/src/main/res/values/colors.xml

@ -4,15 +4,36 @@
<color name="primary">#3F51B5</color> <color name="primary">#3F51B5</color>
<color name="primary_dark">#303F9F</color> <color name="primary_dark">#303F9F</color>
<color name="primary_light">#C5CAE9</color> <color name="primary_light">#C5CAE9</color>
<color name="accent">#FFFFFF</color> <color name="accent">#009688</color>
<color name="primary_text">#E7E7E7</color> <color name="primary_text">#E7E7E7</color>
<color name="secondary_text">#757575</color> <color name="secondary_text">#757575</color>
<color name="card_background">#FFFFFF</color> <color name="card_background">#FFFFFF</color>
<color name="divider">#8B8B8B</color> <color name="divider">#8B8B8B</color>
<!--Lime-->
<!--<color name="primary">#CDDC39</color>
<color name="primary_dark">#AFB42B</color>
<color name="primary_light">#F0F4C3</color>
<color name="accent">#FFC107</color>
<color name="primary_text">#212121</color>
<color name="secondary_text">#757575</color>
<color name="card_background">#212121</color>
<color name="divider">#BDBDBD</color>-->
<!--Cyan-->
<!--<color name="primary">#00BCD4</color>
<color name="primary_dark">#0097A7</color>
<color name="primary_light">#B2EBF2</color>
<color name="accent">#009688</color>
<color name="primary_text">#464646</color>
<color name="secondary_text">#757575</color>
<color name="card_background">#FFFFFF</color>
<color name="divider">#BDBDBD</color>-->
<color name="transparent">#00000000</color> <color name="transparent">#00000000</color>
<color name="white">#FFFFFF</color> <color name="white">#FFFFFF</color>
<color name="black">#000000</color> <color name="black">#000000</color>
<color name="iron">#CCCCCC</color> <color name="iron">#CCCCCC</color>
<color name="card_expand_text_color">#464646</color>
<color name="background">#D3D3D3</color> <color name="background">#D3D3D3</color>
</resources> </resources>

1
app/src/main/res/values/dimens.xml

@ -4,4 +4,5 @@
<dimen name="activity_vertical_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="appbar_padding_top">8dp</dimen> <dimen name="appbar_padding_top">8dp</dimen>
<dimen name="thumbnail_size">80dp</dimen> <dimen name="thumbnail_size">80dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources> </resources>

5
app/src/main/res/values/strings.xml

@ -16,4 +16,9 @@
<string name="username">Username should be here...</string> <string name="username">Username should be here...</string>
<string name="subject">Subject should be here...</string> <string name="subject">Subject should be here...</string>
<string name="post">Post should be here...</string> <string name="post">Post should be here...</string>
<string name="text_first">first</string>
<string name="text_previous">previous</string>
<string name="text_page">Page</string>
<string name="text_next">next</string>
<string name="text_last">last</string>
</resources> </resources>

Loading…
Cancel
Save