Browse Source

Profile activity and parsing. Attachments fix.

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
aff6eca44e
  1. 2
      app/build.gradle
  2. 6
      app/src/main/AndroidManifest.xml
  3. 213
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
  4. 95
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileParser.java
  5. 6
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  6. 15
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  7. 34
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
  8. 9
      app/src/main/java/gr/thmmy/mthmmy/data/Post.java
  9. 121
      app/src/main/res/layout/activity_profile.xml
  10. 15
      app/src/main/res/layout/activity_topic.xml
  11. 7
      app/src/main/res/layout/activity_topic_post_row.xml
  12. 5
      app/src/main/res/values-w820dp/dimens.xml
  13. 1
      app/src/main/res/values/dimens.xml

2
app/build.gradle

@ -10,7 +10,7 @@ android {
minSdkVersion 19
targetSdkVersion 25
versionCode 5
versionName "0.5"
versionName "0.6"
archivesBaseName = "mTHMMY-v$versionName"
}
buildTypes {

6
app/src/main/AndroidManifest.xml

@ -14,7 +14,6 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".activities.main.MainActivity"
android:configChanges="orientation|screenSize"
@ -23,6 +22,7 @@
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
@ -50,6 +50,10 @@
android:value=".activities.main.MainActivity"/>
</activity>
<activity android:name=".activities.BaseActivity"/>
<activity
android:name=".activities.profile.ProfileActivity"
android:theme="@style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>

213
app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java

@ -0,0 +1,213 @@
package gr.thmmy.mthmmy.activities.profile;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.util.ArrayList;
import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.BaseActivity;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.utils.CircleTransform;
import mthmmy.utils.Report;
import okhttp3.Request;
import okhttp3.Response;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.NAME_INDEX;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.PERSONAL_TEXT_INDEX;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.THUMBNAIL_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.parseProfile;
import static gr.thmmy.mthmmy.session.SessionManager.LOGGED_IN;
import static gr.thmmy.mthmmy.session.SessionManager.LOGIN_STATUS;
public class ProfileActivity extends BaseActivity {
//Graphic elements
private ImageView userThumbnail;
private TextView userName;
private TextView personalText;
private LinearLayout mainContent;
private ProgressBar progressBar;
private FloatingActionButton replyFAB;
//Other variables
private ArrayList<String> parsedProfileData;
@SuppressWarnings("unused")
private static final String TAG = "ProfileActivity";
static String PACKAGE_NAME;
private static final int THUMBNAIL_SIZE = 200;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
PACKAGE_NAME = getApplicationContext().getPackageName();
Bundle extras = getIntent().getExtras();
//username = getIntent().getExtras().getString("TOPIC_TITLE");
//Initialize toolbar, drawer and ProgressBar
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(null);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//getSupportActionBar().setDisplayShowHomeEnabled(true);
createDrawer();
progressBar = (ProgressBar) findViewById(R.id.progressBar);
userThumbnail = (ImageView) findViewById(R.id.user_thumbnail);
userName = (TextView) findViewById(R.id.profile_act_username);
personalText = (TextView) findViewById(R.id.profile_act_personal_text);
mainContent = (LinearLayout) findViewById(R.id.profile_act_content);
replyFAB = (FloatingActionButton) findViewById(R.id.profile_fab);
replyFAB.setEnabled(false);
replyFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
int tmp_curr_status = sharedPrefs.getInt(LOGIN_STATUS, -1);
if (tmp_curr_status == -1) {
new AlertDialog.Builder(ProfileActivity.this)
.setTitle("ERROR!")
.setMessage("An error occurred while trying to find your LOGIN_STATUS.\n" +
"Please sent below info to developers:\n"
+ getLocalClassName() + "." + "l"
+ Thread.currentThread().getStackTrace()[1].getLineNumber())
.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Todo
//Maybe sent info back to developers?
}
})
.show();
} else if (tmp_curr_status != LOGGED_IN) {
new AlertDialog.Builder(ProfileActivity.this)
.setMessage("You need to be logged in to sent a personal message!")
.setPositiveButton("Login", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(ProfileActivity.this, LoginActivity.class);
startActivity(intent);
finish();
overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.show();
} else {
//TODO
//PM
}
}
});
new ProfileTask().execute(extras.getString("PROFILE_URL")); //Attempt data parsing
}
public class ProfileTask extends AsyncTask<String, Void, Boolean> {
//Class variables
private static final String TAG = "TopicTask"; //Separate tag for AsyncTask
//Show a progress bar until done
protected void onPreExecute() {
progressBar.setVisibility(ProgressBar.VISIBLE);
replyFAB.setEnabled(false);
}
protected Boolean doInBackground(String... strings) {
Document document;
String pageUrl = strings[0]; //This page's url
Request request = new Request.Builder()
.url(pageUrl)
.build();
try {
Response response = client.newCall(request).execute();
document = Jsoup.parse(response.body().string());
//long parseStartTime = System.nanoTime();
parsedProfileData = parseProfile(document); //Parse data
//long parseEndTime = System.nanoTime();
return true;
} catch (SSLHandshakeException e) {
Report.w(TAG, "Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
Report.e("TAG", "ERROR", e);
}
return false;
}
protected void onPostExecute(Boolean result) {
if (!result) { //Parse failed!
//Should never happen
Toast.makeText(getBaseContext()
, "Fatal error!\n Aborting...", Toast.LENGTH_LONG).show();
finish();
}
//Parse was successful
progressBar.setVisibility(ProgressBar.INVISIBLE); //Hide progress bar
populateLayout(); //Show parsed data
}
}
private void populateLayout() {
if (parsedProfileData.get(THUMBNAIL_URL) != null)
Picasso.with(this)
.load(parsedProfileData.get(THUMBNAIL_URL))
.resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
.centerCrop()
.error(ResourcesCompat.getDrawable(this.getResources()
, R.drawable.ic_default_user_thumbnail, null))
.placeholder(ResourcesCompat.getDrawable(this.getResources()
, R.drawable.ic_default_user_thumbnail, null))
.transform(new CircleTransform())
.into(userThumbnail);
userName.setText(parsedProfileData.get(NAME_INDEX));
if (parsedProfileData.get(PERSONAL_TEXT_INDEX) != null) {
personalText.setVisibility(View.VISIBLE);
personalText.setText(parsedProfileData.get(PERSONAL_TEXT_INDEX));
} else {
personalText.setVisibility(View.GONE);
}
for (int i = PERSONAL_TEXT_INDEX; i < parsedProfileData.size(); ++i) {
TextView entry = new TextView(this);
entry.setTextColor(getResources().getColor(R.color.primary_text));
entry.setText(Html.fromHtml(parsedProfileData.get(i)));
mainContent.addView(entry);
}
}
}

95
app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileParser.java

@ -0,0 +1,95 @@
package gr.thmmy.mthmmy.activities.profile;
import android.util.Log;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.Objects;
import mthmmy.utils.Report;
class ProfileParser {
//Parsing variables
private static String nameSelect;
private static String signatureSelect;
//Other variables
@SuppressWarnings("unused")
private static final String TAG = "ProfileParser";
static final int THUMBNAIL_URL = 0;
static final int NAME_INDEX = 1;
static final int PERSONAL_TEXT_INDEX = 2;
static ArrayList<String> parseProfile(Document doc) {
defineLanguage(doc);
//Method's variables
ArrayList<String> returnArray = new ArrayList<>();
//Contains all summary's rows
Elements summaryRows = doc.select("td.windowbg:nth-child(1)");
{ //Find thumbnail url
Element tmpEl = doc.select(".bordercolor img.avatar").first();
if (tmpEl != null)
returnArray.add(THUMBNAIL_URL, tmpEl.attr("abs:src"));
else //User doesn't have an avatar
returnArray.add(THUMBNAIL_URL, null);
}
{ //Find username
Element tmpEl = summaryRows.select("tr:contains(" + nameSelect + ")").first();
if (tmpEl != null) {
returnArray.add(NAME_INDEX, tmpEl.select("td").get(1).text());
} else {
//Should never get here!
//Something is wrong.
Report.e(TAG, "An error occurred while trying to find profile's username.");
}
}
{ //Find personal text
String tmpPersonalText = doc.select("td.windowbg:nth-child(2)").first().text().trim();
returnArray.add(PERSONAL_TEXT_INDEX, tmpPersonalText);
}
for (Element row : summaryRows.select("tr")) {
String rowText = row.text(), tmpHtml = "";
if (row.select("td").size() == 1)
tmpHtml = "";
else if (rowText.contains(signatureSelect)) {
tmpHtml = row.html();
} else if (!rowText.contains(nameSelect)) {
if (Objects.equals(row.select("td").get(1).text(), ""))
continue;
tmpHtml = "<b>" + row.select("td").first().text() + "</b> "
+ row.select("td").get(1).text();
}
returnArray.add(tmpHtml);
}
return returnArray;
}
private static void defineLanguage(Document doc) {
//English parsing variables
final String en_nameSelect = "Name";
final String en_signatureSelect = "Signature";
//Greek parsing variables
final String gr_nameSelect = "Όνομα";
final String gr_signatureSelect = "Υπογραφή";
if (doc.select("h3").text().contains("Καλώς ορίσατε")) {
nameSelect = gr_nameSelect;
signatureSelect = gr_signatureSelect;
} else { //Default is english (eg. guest's language)
nameSelect = en_nameSelect;
signatureSelect = en_signatureSelect;
}
}
}

6
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -131,7 +131,7 @@ public class TopicActivity extends BaseActivity {
nextPage.setEnabled(false);
lastPage.setEnabled(false);
replyFAB = (FloatingActionButton) findViewById(R.id.fab);
replyFAB = (FloatingActionButton) findViewById(R.id.topic_fab);
replyFAB.setEnabled(false);
replyFAB.setOnClickListener(new View.OnClickListener() {
@ -350,7 +350,9 @@ public class TopicActivity extends BaseActivity {
try {
Response response = client.newCall(request).execute();
document = Jsoup.parse(response.body().string());
//long parseStartTime = System.nanoTime();
parse(document); //Parse data
//long parseEndTime = System.nanoTime();
return true;
} catch (SSLHandshakeException e) {
Report.w(TAG, "Certificate problem (please switch to unsafe connection).");
@ -517,7 +519,7 @@ public class TopicActivity extends BaseActivity {
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ PACKAGE_NAME //TODO
+ packageName
+ "/Downloads");
// This location works best if you want the created files to be shared

15
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java

@ -8,6 +8,7 @@ import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.widget.CardView;
@ -34,6 +35,7 @@ import java.util.List;
import java.util.Objects;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import gr.thmmy.mthmmy.data.Post;
import gr.thmmy.mthmmy.utils.CircleTransform;
import mthmmy.utils.Report;
@ -285,6 +287,19 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
holder.header.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (viewProperties.get(holder.getAdapterPosition())[isUserExtraInfoVisibile] &&
!currentPost.isDeleted()) {
Intent intent = new Intent(context, ProfileActivity.class);
Bundle b = new Bundle();
b.putString("PROFILE_URL", currentPost.getProfileURL()); //Profile url
intent.putExtras(b); //Put url to next Intent
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
//((Activity) context).overridePendingTransition(
//R.anim.push_right_in, R.anim.push_left_out);
}
//Change post's viewProperties accordingly
boolean[] tmp = viewProperties.get(holder.getAdapterPosition());
tmp[isUserExtraInfoVisibile] = !tmp[isUserExtraInfoVisibile];

34
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java

@ -23,6 +23,8 @@ class TopicParser {
private static int postDateSubstrSelection;
private static String postNumberSelection;
private static int postNumSubstrSelection;
private static String postAttachedDiv;
private static String postAttachedSubstr;
private static String numberOfPostsSelection;
private static String genderSelection;
private static String genderAltMale;
@ -40,7 +42,7 @@ class TopicParser {
private static final String TAG = "TopicParser";
static int parseCurrentPageIndex(Document doc) {
defineLanguange(doc);
defineLanguage(doc);
int returnPage = 1;
//Contains pages
@ -57,7 +59,7 @@ class TopicParser {
}
static int parseTopicNumberOfPages(Document doc, int thisPage) {
defineLanguange(doc);
defineLanguage(doc);
//Method's variables
int returnPages = 1;
@ -76,7 +78,7 @@ class TopicParser {
}
static ArrayList<Post> parseTopic(Document doc) {
defineLanguange(doc);
defineLanguage(doc);
//Method's variables
final int NO_INDEX = -1;
@ -87,13 +89,14 @@ class TopicParser {
for (Element item : rows) { //For every post
//Variables to pass
String p_userName, p_thumbnailUrl, p_subject, p_post, p_postDate, p_rank,
String p_userName, p_thumbnailUrl, p_subject, p_post, p_postDate, p_profileURL, p_rank,
p_specialRank, p_gender, p_personalText, p_numberOfPosts;
int p_postNum, p_postIndex, p_numberOfStars, p_userColor;
boolean p_isDeleted = false;
ArrayList<String[]> p_attachedFiles;
//Initialize variables
p_profileURL = null;
p_rank = "Rank";
p_specialRank = "Special rank";
p_gender = "";
@ -113,8 +116,10 @@ class TopicParser {
.first().text();
p_userName = p_userName.substring(0, p_userName.indexOf(" " + guestSelection));
p_userColor = USER_COLOR_BLACK;
} else
} else {
p_userName = userName.html();
p_profileURL = userName.attr("href");
}
//Find thumbnail url
Element thumbnailUrl = item.select("img.avatar").first();
@ -182,7 +187,8 @@ class TopicParser {
}
//Find attached file's urls, names and info, if present
Elements postAttachments = item.select("div:containsOwn(downloaded)");
Elements postAttachments = item.select("div:containsOwn(" + postAttachedDiv
+ "):containsOwn(" + postAttachedSubstr + ")");
if (postAttachments != null) {
Elements attachedFiles = postAttachments.select("a");
String postAttachmentsText = postAttachments.text();
@ -199,7 +205,7 @@ class TopicParser {
String postAttachmentsTextSbstr = postAttachmentsText.substring(
postAttachmentsText.indexOf(attachedArray[1]));
attachedArray[2] = postAttachmentsTextSbstr.substring(attachedArray[1].length()
, postAttachmentsTextSbstr.indexOf("times.)"));
, postAttachmentsTextSbstr.indexOf(postAttachedSubstr));
p_attachedFiles.add(attachedArray);
}
@ -262,7 +268,7 @@ class TopicParser {
}
//Add new post in postsList, extended information needed
returnList.add(new Post(p_thumbnailUrl, p_userName, p_subject, p_post
, p_postIndex, p_postNum, p_postDate, p_rank
, p_postIndex, p_postNum, p_postDate, p_profileURL, p_rank
, p_specialRank, p_gender, p_numberOfPosts, p_personalText
, p_numberOfStars, p_userColor, p_attachedFiles));
@ -275,12 +281,14 @@ class TopicParser {
return returnList;
}
private static void defineLanguange(Document doc){
private static void defineLanguage(Document doc){
//English parsing variables
final String en_currentPage = "Pages:";
final String en_postRowSelection = "on";
final String en_userNameSelection = "View the profile of";
final String en_guestSelection = "Guest";
final String en_postAttachedDiv = "downloaded";
final String en_postAttachedSubstr = "times.\\)";
final String en_postsNumberSelection = "Reply #";
final String en_numberOfPostsSelection = "Posts:";
final String en_genderSelection = "Gender:";
@ -292,6 +300,8 @@ class TopicParser {
final String gr_postRowSelection = "στις";
final String gr_userNameSelection = "Εμφάνιση προφίλ του μέλους";
final String gr_guestSelection = "Επισκέπτης";
final String gr_postAttachedDiv = "έγινε λήψη";
final String gr_postAttachedSubstr = "φορές.\\)";
final String gr_postsNumberSelection = "Απάντηση #";
final String gr_numberOfPostsSelection = "Μηνύματα:";
final String gr_genderSelection = "Φύλο:";
@ -303,6 +313,8 @@ class TopicParser {
postRowSelection = gr_postRowSelection;
userNameSelection = gr_userNameSelection;
guestSelection = gr_guestSelection;
postAttachedDiv = gr_postAttachedDiv;
postAttachedSubstr = gr_postAttachedSubstr;
postDateSubstrSelection = 6;
postNumberSelection = gr_postsNumberSelection;
postNumSubstrSelection = 12;
@ -311,11 +323,13 @@ class TopicParser {
genderAltMale = gr_genderAltMale;
genderAltFemale = gr_genderAltFemale;
}
else{ //Means default is english (eg. guest's language)
else{ //Default is english (eg. guest's language)
currentPage = en_currentPage;
postRowSelection = en_postRowSelection;
userNameSelection = en_userNameSelection;
guestSelection = en_guestSelection;
postAttachedDiv = en_postAttachedDiv;
postAttachedSubstr = en_postAttachedSubstr;
postDateSubstrSelection = 4;
postNumberSelection = en_postsNumberSelection;
postNumSubstrSelection = 9;

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

@ -11,6 +11,7 @@ public class Post {
private final int postIndex;
//Extra info
private final String profileURL;
private final int postNumber;
private final String postDate;
private final boolean isDeleted;
@ -24,7 +25,7 @@ public class Post {
private final ArrayList<String[]> attachedFiles;
public Post(String thumbnailUrl, String author, String subject, String content
, int postIndex, int postNumber, String postDate, String rank
, int postIndex, int postNumber, String postDate, String profileURl, String rank
, String special_rank, String gender, String numberOfPosts
, String personalText, int numberOfStars, int userColor
, ArrayList<String[]> attachedFiles) {
@ -36,6 +37,7 @@ public class Post {
this.postNumber = postNumber;
this.postDate = postDate;
this.isDeleted = false;
this.profileURL = profileURl;
this.rank = rank;
this.specialRank = special_rank;
this.gender = gender;
@ -57,6 +59,7 @@ public class Post {
this.postNumber = postNumber;
this.postDate = postDate;
this.isDeleted = true;
profileURL = null;
this.userColor = userColor;
rank = "Rank";
specialRank = "Special rank";
@ -100,6 +103,10 @@ public class Post {
return isDeleted;
}
public String getProfileURL() {
return profileURL;
}
public String getRank() {
return rank;
}

121
app/src/main/res/layout/activity_profile.xml

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.profile.ProfileActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/ToolbarTheme">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/main.collapsing"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/user_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:contentDescription="@string/thumbnail"
android:fitsSystemWindows="true"
android:src="@drawable/ic_default_user_thumbnail"
android:transitionName="user_thumbnail"
app:layout_collapseMode="parallax"/>
<TextView
android:id="@+id/profile_act_personal_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/primary_text"
android:visibility="gone"/>
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:gravity="center"
app:popupTheme="@style/ToolbarTheme">
<TextView
android:id="@+id/profile_act_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/accent"
android:textSize="25sp"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:theme="@style/AppTheme"
android:visibility="invisible"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|center"/>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|start"
android:background="@color/background"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:scrollbars="none"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|center"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/profile_act_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/profile_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margins"
android:transitionName="fab"
app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior"
app:srcCompat="@drawable/ic_add_fab"/>
</android.support.design.widget.CoordinatorLayout>

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

@ -7,7 +7,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.main.MainActivity">
tools:context=".activities.topic.TopicActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
@ -24,7 +24,6 @@
android:transitionName="toolbar"
app:popupTheme="@style/ToolbarTheme">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
@ -98,19 +97,19 @@
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:indeterminate="true"
android:theme="@style/AppTheme"
android:visibility="invisible"/>
android:visibility="invisible"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|center"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:id="@+id/topic_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="42dp"
android:layout_marginBottom="54dp"
android:layout_marginEnd="@dimen/fab_margins"
android:transitionName="fab"
app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior"
app:srcCompat="@drawable/ic_add_fab"/>

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

@ -89,7 +89,8 @@
android:contentDescription="@string/thumbnail"
android:maxHeight="@dimen/thumbnail_size"
android:maxWidth="@dimen/thumbnail_size"
android:src="@drawable/ic_default_user_thumbnail"/>
android:src="@drawable/ic_default_user_thumbnail"
android:transitionName="user_thumbnail"/>
</FrameLayout>
<TextView
@ -234,9 +235,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="9dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="9dp">
android:paddingRight="16dp">
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

5
app/src/main/res/values-w820dp/dimens.xml

@ -3,4 +3,9 @@
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
<dimen name="activity_vertical_margin">64dp</dimen>
<dimen name="appbar_padding_top">32dp</dimen>
<dimen name="thumbnail_size">176dp</dimen>
<dimen name="quote_button">144dp</dimen>
<dimen name="fab_margins">64dp</dimen>
</resources>

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

@ -5,4 +5,5 @@
<dimen name="appbar_padding_top">8dp</dimen>
<dimen name="thumbnail_size">44dp</dimen>
<dimen name="quote_button">36dp</dimen>
<dimen name="fab_margins">16dp</dimen>
</resources>

Loading…
Cancel
Save