Browse Source

StatsFragment completion and minor fixes

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
9e9b79a6d3
  1. 6
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
  2. 5
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
  3. 351
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
  4. 19
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
  5. 10
      app/src/main/res/drawable/line_chart_gradient.xml
  6. 7
      app/src/main/res/layout-v21/activity_profile.xml
  7. 4
      app/src/main/res/layout/activity_main.xml
  8. 6
      app/src/main/res/layout/activity_profile.xml
  9. 29
      app/src/main/res/layout/profile_fragment_stats.xml
  10. 1
      app/src/main/res/values/strings.xml

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

@ -27,6 +27,7 @@ import org.jsoup.nodes.Element;
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;
@ -34,6 +35,7 @@ import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.base.BaseActivity;
import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment; import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment;
import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment;
import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment; import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment;
import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.data.TopicSummary; import gr.thmmy.mthmmy.data.TopicSummary;
@ -105,7 +107,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar);
ImageView thumbnailView = (ImageView) findViewById(R.id.user_thumbnail); ImageView thumbnailView = (ImageView) findViewById(R.id.user_thumbnail);
if (thumbnailUrl != null) if (thumbnailUrl != null && !Objects.equals(thumbnailUrl, ""))
//noinspection ConstantConditions //noinspection ConstantConditions
Picasso.with(this) Picasso.with(this)
.load(thumbnailUrl) .load(thumbnailUrl)
@ -252,7 +254,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(SummaryFragment.newInstance(profilePage), "SUMMARY"); adapter.addFrag(SummaryFragment.newInstance(profilePage), "SUMMARY");
adapter.addFrag(LatestPostsFragment.newInstance(profileUrl), "LATEST POSTS"); adapter.addFrag(LatestPostsFragment.newInstance(profileUrl), "LATEST POSTS");
//adapter.addFrag(new ); adapter.addFrag(StatsFragment.newInstance(profileUrl), "STATS");
viewPager.setAdapter(adapter); viewPager.setAdapter(adapter);
} }

5
app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java

@ -5,7 +5,6 @@ import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -175,10 +174,8 @@ public class LatestPostsFragment extends BaseFragment {
} }
protected Boolean doInBackground(String... profileUrl) { protected Boolean doInBackground(String... profileUrl) {
String pageUrl = profileUrl[0];
Request request = new Request.Builder() Request request = new Request.Builder()
.url(pageUrl) .url(profileUrl[0])
.build(); .build();
try { try {
Response response = BaseActivity.getClient().newCall(request).execute(); Response response = BaseActivity.getClient().newCall(request).execute();

351
app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java

@ -1,8 +1,355 @@
package gr.thmmy.mthmmy.activities.profile.stats; package gr.thmmy.mthmmy.activities.profile.stats;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.github.mikephil.charting.charts.HorizontalBarChart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.formatter.PercentFormatter;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.base.BaseActivity;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mthmmy.utils.Report;
import okhttp3.Request;
import okhttp3.Response;
public class StatsFragment extends Fragment {
/**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "StatsFragment";
/**
* The key to use when putting profile's url String to {@link StatsFragment}'s Bundle.
*/
static final String PROFILE_URL = "PROFILE_DOCUMENT";
private String profileUrl;
private ProfileStatsTask profileStatsTask;
private LinearLayout mainContent;
private MaterialProgressBar progressBar;
private boolean haveParsed = false;
private String generalStatisticsTitle = "", generalStatistics = "", postingActivityByTimeTitle = "", mostPopularBoardsByPostsTitle = "", mostPopularBoardsByActivityTitle = "";
private List<Entry> postingActivityByTime = new ArrayList<>();
private List<BarEntry> mostPopularBoardsByPosts = new ArrayList<>(), mostPopularBoardsByActivity = new ArrayList<>();
private ArrayList<String> mostPopularBoardsByPostsLabels = new ArrayList<>(), mostPopularBoardsByActivityLabels = new ArrayList<>();
public StatsFragment() {
// Required empty public constructor
}
/** /**
* Created by apostolof on 1/1/17. * Use ONLY this factory method to create a new instance of this fragment using the provided
* parameters.
*
* @param profileUrl String containing this profile's url
* @return A new instance of fragment Stats.
*/ */
public static StatsFragment newInstance(String profileUrl) {
StatsFragment fragment = new StatsFragment();
Bundle args = new Bundle();
args.putString(PROFILE_URL, profileUrl);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
profileUrl = getArguments().getString(PROFILE_URL);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.profile_fragment_stats, container, false);
mainContent = (LinearLayout) rootView.findViewById(R.id.main_content);
progressBar = (MaterialProgressBar) rootView.findViewById(R.id.progressBar);
if (haveParsed)
populateLayout();
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!haveParsed) {
profileStatsTask = new ProfileStatsTask();
profileStatsTask.execute(profileUrl + ";sa=statPanel");
}
Report.d(TAG, "onActivityCreated");
}
@Override
public void onDestroy() {
super.onDestroy();
if (profileStatsTask != null && profileStatsTask.getStatus() != AsyncTask.Status.RUNNING)
profileStatsTask.cancel(true);
}
/**
* An {@link AsyncTask} that handles asynchronous parsing of a profile page's data.
* {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #()}
* to build graphics.
* <p>
* <p>Calling ProfileSummaryTask's {@link AsyncTask#execute execute} method needs to have profile's url
* as String parameter!</p>
*/
public class ProfileStatsTask extends AsyncTask<String, Void, Boolean> {
//Class variables
/**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "ProfileStatsTask"; //Separate tag for AsyncTask
@Override
protected void onPreExecute() {
progressBar.setVisibility(ProgressBar.VISIBLE);
haveParsed = true;
}
@Override
protected Boolean doInBackground(String... profileUrl) {
Request request = new Request.Builder()
.url(profileUrl[0])
.build();
try {
Response response = BaseActivity.getClient().newCall(request).execute();
return parseStats(Jsoup.parse(response.body().string()));
} catch (SSLHandshakeException e) {
Report.w(TAG, "Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
Report.e("TAG", "ERROR", e);
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) { //Parse failed!
Toast.makeText(getContext()
, "Fatal error!\n Aborting...", Toast.LENGTH_LONG).show();
getActivity().finish();
}
//Parse was successful
progressBar.setVisibility(ProgressBar.INVISIBLE);
populateLayout();
}
private boolean parseStats(Document statsPage) {
if (statsPage.select("table.bordercolor>tbody>tr").size() != 6)
return false; //It's my profile
{
Elements titleRows = statsPage.select("table.bordercolor>tbody>tr.titlebg");
generalStatisticsTitle = titleRows.first().text();
postingActivityByTimeTitle = titleRows.get(1).text();
mostPopularBoardsByPostsTitle = titleRows.last().select("td").first().text();
mostPopularBoardsByActivityTitle = titleRows.last().select("td").last().text();
}
{
Elements statsRows = statsPage.select("table.bordercolor>tbody>tr:not(.titlebg)");
{
Elements generalStatisticsRows = statsRows.first().select("tbody>tr");
for (Element generalStatisticsRow : generalStatisticsRows)
generalStatistics += generalStatisticsRow.text() + "\n";
generalStatistics = generalStatistics.trim();
}
{
Elements postingActivityByTimeCols = statsRows.get(1).select(">td").last()
.select("tr").first().select("td[width=4%]");
int i = -1;
for (Element postingActivityByTimeColumn : postingActivityByTimeCols) {
postingActivityByTime.add(new Entry(++i, Float.parseFloat(postingActivityByTimeColumn
.select("img").first().attr("height"))));
}
}
{
Elements mostPopularBoardsByPostsRows = statsRows.last().select(">td").get(1)
.select(">table>tbody>tr");
int i = mostPopularBoardsByPostsRows.size();
for (Element mostPopularBoardsByPostsRow : mostPopularBoardsByPostsRows) {
Elements dataCols = mostPopularBoardsByPostsRow.select("td");
mostPopularBoardsByPosts.add(new BarEntry(--i,
Integer.parseInt(dataCols.last().text())));
mostPopularBoardsByPostsLabels.add(dataCols.first().text());
}
}
{
Elements mostPopularBoardsByActivityRows = statsRows.last().select(">td").last()
.select(">table>tbody>tr");
Log.d(TAG, String.valueOf(mostPopularBoardsByActivityRows.size()));
int i = mostPopularBoardsByActivityRows.size();
for (Element mostPopularBoardsByActivityRow : mostPopularBoardsByActivityRows) {
Elements dataCols = mostPopularBoardsByActivityRow.select("td");
String tmp = dataCols.last().text();
mostPopularBoardsByActivity.add(new BarEntry(--i,
Float.parseFloat(tmp.substring(0, tmp.indexOf("%")))));
mostPopularBoardsByActivityLabels.add(dataCols.first().text());
}
}
}
return true;
}
}
private void populateLayout() {
((TextView) mainContent.findViewById(R.id.general_statistics_title))
.setText(generalStatisticsTitle);
((TextView) mainContent.findViewById(R.id.general_statistics))
.setText(generalStatistics);
((TextView) mainContent.findViewById(R.id.posting_activity_by_time_title))
.setText(postingActivityByTimeTitle);
LineChart postingActivityByTimeChart = (LineChart) mainContent
.findViewById(R.id.posting_activity_by_time_chart);
postingActivityByTimeChart.setDescription(null);
postingActivityByTimeChart.getLegend().setEnabled(false);
postingActivityByTimeChart.setScaleYEnabled(false);
postingActivityByTimeChart.setDrawBorders(true);
postingActivityByTimeChart.getAxisLeft().setEnabled(false);
postingActivityByTimeChart.getAxisRight().setEnabled(false);
XAxis postingActivityByTimeChartXAxis = postingActivityByTimeChart.getXAxis();
postingActivityByTimeChartXAxis.setTextColor(Color.WHITE);
postingActivityByTimeChartXAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
postingActivityByTimeChartXAxis.setDrawLabels(true);
postingActivityByTimeChartXAxis.setLabelCount(24, false);
postingActivityByTimeChartXAxis.setGranularity(1f);
LineDataSet postingActivityByTimeDataSet = new LineDataSet(postingActivityByTime, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
postingActivityByTimeDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_chart_gradient, null));
} else
//noinspection deprecation
postingActivityByTimeDataSet.setFillDrawable(getResources().getDrawable(R.drawable.line_chart_gradient));
postingActivityByTimeDataSet.setDrawFilled(true);
postingActivityByTimeDataSet.setDrawCircles(false);
postingActivityByTimeDataSet.setDrawValues(false);
LineData postingActivityByTimeData = new LineData(postingActivityByTimeDataSet);
postingActivityByTimeChart.setData(postingActivityByTimeData);
postingActivityByTimeChart.invalidate();
((TextView) mainContent.findViewById(R.id.most_popular_boards_by_posts_title))
.setText(mostPopularBoardsByPostsTitle);
public class StatsFragment { HorizontalBarChart mostPopularBoardsByPostsChart = (HorizontalBarChart) mainContent.
findViewById(R.id.most_popular_boards_by_posts_chart);
mostPopularBoardsByPostsChart.setDescription(null);
mostPopularBoardsByPostsChart.getLegend().setEnabled(false);
mostPopularBoardsByPostsChart.setScaleEnabled(false);
mostPopularBoardsByPostsChart.setDrawBorders(true);
mostPopularBoardsByPostsChart.getAxisLeft().setEnabled(false);
XAxis mostPopularBoardsByPostsChartXAxis = mostPopularBoardsByPostsChart.getXAxis();
mostPopularBoardsByPostsChartXAxis.setPosition(XAxis.XAxisPosition.TOP_INSIDE);
mostPopularBoardsByPostsChartXAxis.setTextColor(Color.WHITE);
mostPopularBoardsByPostsChartXAxis.setLabelCount(mostPopularBoardsByPostsLabels.size());
mostPopularBoardsByPostsChartXAxis.setValueFormatter(new MyXAxisValueFormatter(mostPopularBoardsByPostsLabels));
YAxis mostPopularBoardsByPostsChartYAxis = mostPopularBoardsByPostsChart.getAxisRight();
mostPopularBoardsByPostsChartYAxis.setTextColor(Color.WHITE);
mostPopularBoardsByPostsChartYAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
mostPopularBoardsByPostsChartYAxis.setDrawLabels(true);
mostPopularBoardsByPostsChartYAxis.setLabelCount(10, false);
mostPopularBoardsByPostsChartYAxis.setGranularity(1f);
BarDataSet mostPopularBoardsByPostsDataSet = new BarDataSet(mostPopularBoardsByPosts, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mostPopularBoardsByPostsDataSet.setColors(getResources().getColor(R.color.accent, null));
} else
//noinspection deprecation
mostPopularBoardsByPostsDataSet.setColors(getResources().getColor(R.color.accent));
mostPopularBoardsByPostsDataSet.setDrawValues(false);
mostPopularBoardsByPostsDataSet.setValueTextColor(Color.WHITE);
BarData mostPopularBoardsByPostsData = new BarData(mostPopularBoardsByPostsDataSet);
mostPopularBoardsByPostsData.setDrawValues(false);
mostPopularBoardsByPostsData.setValueTextColor(Color.WHITE);
mostPopularBoardsByPostsChart.setData(mostPopularBoardsByPostsData);
mostPopularBoardsByPostsChart.invalidate();
((TextView) mainContent.findViewById(R.id.most_popular_boards_by_activity_title))
.setText(mostPopularBoardsByActivityTitle);
HorizontalBarChart mostPopularBoardsByActivityChart = (HorizontalBarChart) mainContent.
findViewById(R.id.most_popular_boards_by_activity_chart);
mostPopularBoardsByActivityChart.setDescription(null);
mostPopularBoardsByActivityChart.getLegend().setEnabled(false);
mostPopularBoardsByActivityChart.setScaleEnabled(false);
mostPopularBoardsByActivityChart.setDrawBorders(true);
mostPopularBoardsByActivityChart.getAxisLeft().setEnabled(false);
XAxis mostPopularBoardsByActivityChartXAxis = mostPopularBoardsByActivityChart.getXAxis();
mostPopularBoardsByActivityChartXAxis.setPosition(XAxis.XAxisPosition.TOP_INSIDE);
mostPopularBoardsByActivityChartXAxis.setTextColor(Color.WHITE);
mostPopularBoardsByActivityChartXAxis.setLabelCount(mostPopularBoardsByActivity.size());
mostPopularBoardsByActivityChartXAxis.setValueFormatter(new MyXAxisValueFormatter(mostPopularBoardsByActivityLabels));
YAxis mostPopularBoardsByActivityChartYAxis = mostPopularBoardsByActivityChart.getAxisRight();
mostPopularBoardsByActivityChartYAxis.setValueFormatter(new PercentFormatter());
mostPopularBoardsByActivityChartYAxis.setTextColor(Color.WHITE);
mostPopularBoardsByActivityChartYAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
mostPopularBoardsByActivityChartYAxis.setDrawLabels(true);
mostPopularBoardsByActivityChartYAxis.setLabelCount(10, false);
BarDataSet mostPopularBoardsByActivityDataSet = new BarDataSet(mostPopularBoardsByActivity, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mostPopularBoardsByActivityDataSet.setColors(getResources().getColor(R.color.accent, null));
} else
//noinspection deprecation
mostPopularBoardsByActivityDataSet.setColors(getResources().getColor(R.color.accent));
mostPopularBoardsByActivityDataSet.setDrawValues(false);
mostPopularBoardsByActivityDataSet.setValueTextColor(Color.WHITE);
BarData mostPopularBoardsByActivityData = new BarData(mostPopularBoardsByActivityDataSet);
mostPopularBoardsByActivityData.setDrawValues(false);
mostPopularBoardsByActivityData.setValueTextColor(Color.WHITE);
mostPopularBoardsByActivityChart.setData(mostPopularBoardsByActivityData);
mostPopularBoardsByActivityChart.invalidate();
}
class MyXAxisValueFormatter implements IAxisValueFormatter {
private ArrayList<String> mValues;
MyXAxisValueFormatter(ArrayList<String> values) {
this.mValues = values;
}
@Override
public String getFormattedValue(float value, AxisBase axis) {
return mValues.get((int) value);
}
}
} }

19
app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java

@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import mthmmy.utils.Report; import mthmmy.utils.Report;
@ -77,6 +76,16 @@ public class SummaryFragment extends Fragment {
parsedProfileSummaryData = new ArrayList<>(); parsedProfileSummaryData = new ArrayList<>();
} }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.profile_fragment_summary, container, false);
mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content);
if (!parsedProfileSummaryData.isEmpty())
populateLayout();
return rootView;
}
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
@ -94,14 +103,6 @@ public class SummaryFragment extends Fragment {
profileSummaryTask.cancel(true); profileSummaryTask.cancel(true);
} }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.profile_fragment_summary, container, false);
mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content);
return rootView;
}
/** /**
* An {@link AsyncTask} that handles asynchronous parsing of a profile page's data. * An {@link AsyncTask} that handles asynchronous parsing of a profile page's data.
* {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #populateLayout()} * {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #populateLayout()}

10
app/src/main/res/drawable/line_chart_gradient.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="@color/accent"
android:startColor="@color/background"
android:type="linear"/>
</shape>

7
app/src/main/res/layout-v21/activity_profile.xml

@ -75,7 +75,12 @@
<android.support.design.widget.TabLayout <android.support.design.widget.TabLayout
android:id="@+id/profile_tabs" android:id="@+id/profile_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
android:gravity="center"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabSelectedTextColor="@color/accent"
app:tabTextColor="@color/white"/>
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager <android.support.v4.view.ViewPager

4
app/src/main/res/layout/activity_main.xml

@ -27,7 +27,9 @@
<android.support.design.widget.TabLayout <android.support.design.widget.TabLayout
android:id="@+id/tabs" android:id="@+id/tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
app:tabSelectedTextColor="@color/accent"
app:tabTextColor="@color/white"/>
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager <android.support.v4.view.ViewPager

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

@ -75,9 +75,11 @@
android:id="@+id/profile_tabs" android:id="@+id/profile_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tabMode="fixed" android:gravity="center"
app:tabGravity="fill" app:tabGravity="fill"
android:gravity="center"/> app:tabMode="fixed"
app:tabSelectedTextColor="@color/accent"
app:tabTextColor="@color/white"/>
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager <android.support.v4.view.ViewPager

29
app/src/main/res/layout/profile_fragment_stats.xml

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
@ -10,6 +15,7 @@
android:background="@color/background"> android:background="@color/background">
<LinearLayout <LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -44,7 +50,8 @@
<com.github.mikephil.charting.charts.LineChart <com.github.mikephil.charting.charts.LineChart
android:id="@+id/posting_activity_by_time_chart" android:id="@+id/posting_activity_by_time_chart"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="250dp"
android:layout_marginBottom="4dp"/>
<TextView <TextView
android:id="@+id/most_popular_boards_by_posts_title" android:id="@+id/most_popular_boards_by_posts_title"
@ -59,7 +66,8 @@
<com.github.mikephil.charting.charts.HorizontalBarChart <com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/most_popular_boards_by_posts_chart" android:id="@+id/most_popular_boards_by_posts_chart"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="250dp"
android:layout_marginBottom="4dp"/>
<TextView <TextView
android:id="@+id/most_popular_boards_by_activity_title" android:id="@+id/most_popular_boards_by_activity_title"
@ -74,6 +82,19 @@
<com.github.mikephil.charting.charts.HorizontalBarChart <com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/most_popular_boards_by_activity_chart" android:id="@+id/most_popular_boards_by_activity_chart"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="250dp"
android:layout_marginBottom="4dp"/>
</LinearLayout> </LinearLayout>
</android.support.v4.widget.NestedScrollView> </android.support.v4.widget.NestedScrollView>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progressBar"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:indeterminate="true"
android:visibility="invisible"
app:mpb_indeterminateTint="@color/accent"
app:mpb_progressStyle="horizontal"/>
</RelativeLayout>

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

@ -37,6 +37,7 @@
<string name="fa_file_powerpoint_o">&#xf1c4;</string> <string name="fa_file_powerpoint_o">&#xf1c4;</string>
<string name="fa_file_excel_o">&#xf1c3;</string> <string name="fa_file_excel_o">&#xf1c3;</string>
<string name="fa_file_video_o">&#xf1c8;</string> <string name="fa_file_video_o">&#xf1c8;</string>
<string name="fa_info_circle">&#xf05a;</string>
<string name="user_number_of_posts">#%1$d</string> <string name="user_number_of_posts">#%1$d</string>

Loading…
Cancel
Save