Show a ViewPager with change details on click on change in list
For now the ViewPager only contains tabs for the commit message and
the file list. More tabs will be added in follow-up changes.
Change-Id: I7747f33191f97e9edfe27af9c975e1b20f3432d3
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/app/src/main/java/com/google/reviewit/AbandonFragment.java b/app/src/main/java/com/google/reviewit/AbandonFragment.java
index dcc2137..18fd229 100644
--- a/app/src/main/java/com/google/reviewit/AbandonFragment.java
+++ b/app/src/main/java/com/google/reviewit/AbandonFragment.java
@@ -14,10 +14,10 @@
package com.google.reviewit;
-import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
import android.view.View;
import com.google.gerrit.extensions.restapi.RestApiException;
diff --git a/app/src/main/java/com/google/reviewit/AddReviewerFragment.java b/app/src/main/java/com/google/reviewit/AddReviewerFragment.java
index 7e25d7f..bfffba8 100644
--- a/app/src/main/java/com/google/reviewit/AddReviewerFragment.java
+++ b/app/src/main/java/com/google/reviewit/AddReviewerFragment.java
@@ -14,11 +14,11 @@
package com.google.reviewit;
-import android.app.Fragment;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
diff --git a/app/src/main/java/com/google/reviewit/BaseFragment.java b/app/src/main/java/com/google/reviewit/BaseFragment.java
index e64d33a..d8eb422 100644
--- a/app/src/main/java/com/google/reviewit/BaseFragment.java
+++ b/app/src/main/java/com/google/reviewit/BaseFragment.java
@@ -14,9 +14,6 @@
package com.google.reviewit;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
@@ -24,6 +21,9 @@
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -52,7 +52,7 @@
return root;
}
- private void reset(ViewGroup container) {
+ protected void reset(ViewGroup container) {
container.removeAllViews();
MainActivity activity = ((MainActivity) getActivity());
diff --git a/app/src/main/java/com/google/reviewit/CommitMessageFragment.java b/app/src/main/java/com/google/reviewit/CommitMessageFragment.java
new file mode 100644
index 0000000..75e078e
--- /dev/null
+++ b/app/src/main/java/com/google/reviewit/CommitMessageFragment.java
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.reviewit;
+
+import android.os.Bundle;
+import android.support.annotation.StringRes;
+import android.widget.TextView;
+
+import com.google.reviewit.app.Change;
+import com.google.reviewit.util.FormatUtil;
+import com.google.reviewit.util.Linkifier;
+
+public class CommitMessageFragment extends PageFragment {
+ private Change change;
+
+ @Override
+ protected int getLayout() {
+ return R.layout.content_commit_message;
+ }
+
+ @Override
+ public @StringRes
+ int getTitle() {
+ return R.string.commit_message_title;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ tv(R.id.subject).setText(change.currentRevision().commit.subject);
+
+ TextView commitMsg = tv(R.id.commitMessage);
+ commitMsg.setText(FormatUtil.formatMessage(change));
+ (new Linkifier(getApp())).linkifyCommitMessage(commitMsg);
+ }
+
+ public void setChange(Change change) {
+ this.change = change;
+ }
+}
diff --git a/app/src/main/java/com/google/reviewit/FileListFragment.java b/app/src/main/java/com/google/reviewit/FileListFragment.java
new file mode 100644
index 0000000..16ddef5
--- /dev/null
+++ b/app/src/main/java/com/google/reviewit/FileListFragment.java
@@ -0,0 +1,69 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.reviewit;
+
+import android.os.Bundle;
+import android.support.annotation.StringRes;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.google.gerrit.extensions.common.FileInfo;
+import com.google.reviewit.app.Change;
+import com.google.reviewit.widget.FileEntry;
+
+import java.util.Map;
+
+import static com.google.reviewit.util.LayoutUtil.matchAndFixedLayout;
+
+public class FileListFragment extends PageFragment {
+ private Change change;
+
+ @Override
+ protected int getLayout() {
+ return R.layout.content_file_list;
+ }
+
+ @Override
+ public @StringRes int getTitle() {
+ return R.string.file_list_title;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ ViewGroup fileList = vg(R.id.fileList);
+ for (Map.Entry<String, FileInfo> entry :
+ change.currentRevision().files.entrySet()) {
+ FileEntry fileEntry = new FileEntry(getContext());
+ fileEntry.init((BaseFragment)getParentFragment(), entry.getKey(),
+ entry.getValue());
+ fileList.addView(fileEntry);
+ addSeparator(fileList);
+ }
+ }
+
+ public void setChange(Change change) {
+ this.change = change;
+ }
+
+ private void addSeparator(ViewGroup viewGroup) {
+ View separator = new View(getContext());
+ separator.setLayoutParams(
+ matchAndFixedLayout(widgetUtil.dpToPx(1)));
+ separator.setBackgroundColor(widgetUtil.color(R.color.separator));
+ viewGroup.addView(separator);
+ }
+}
diff --git a/app/src/main/java/com/google/reviewit/MainActivity.java b/app/src/main/java/com/google/reviewit/MainActivity.java
index d509f67..4960f72 100644
--- a/app/src/main/java/com/google/reviewit/MainActivity.java
+++ b/app/src/main/java/com/google/reviewit/MainActivity.java
@@ -15,13 +15,13 @@
package com.google.reviewit;
import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
@@ -174,7 +174,7 @@
}
private void displayView(Fragment fragment) {
- FragmentManager fragmentManager = getFragmentManager();
+ FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.mainFrame, fragment)
.addToBackStack(null)
@@ -229,7 +229,8 @@
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
- Fragment fragment = getFragmentManager().findFragmentById(R.id.mainFrame);
+ Fragment fragment = getSupportFragmentManager()
+ .findFragmentById(R.id.mainFrame);
if (fragment instanceof DispatchTouchEventAware) {
((DispatchTouchEventAware) fragment).dispatchTouchEvent(event);
}
@@ -239,7 +240,8 @@
@Override
public void onBackPressed() {
- Fragment fragment = getFragmentManager().findFragmentById(R.id.mainFrame);
+ Fragment fragment = getSupportFragmentManager()
+ .findFragmentById(R.id.mainFrame);
if (fragment instanceof OnBackPressedAware) {
if (((OnBackPressedAware) fragment).onBackPressed()) {
return;
diff --git a/app/src/main/java/com/google/reviewit/PageFragment.java b/app/src/main/java/com/google/reviewit/PageFragment.java
new file mode 100644
index 0000000..044ea77
--- /dev/null
+++ b/app/src/main/java/com/google/reviewit/PageFragment.java
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.reviewit;
+
+import android.support.annotation.StringRes;
+import android.view.ViewGroup;
+
+public abstract class PageFragment extends BaseFragment {
+ @Override
+ protected void reset(ViewGroup container) {
+ }
+
+ public abstract @StringRes int getTitle();
+}
diff --git a/app/src/main/java/com/google/reviewit/PagedChangeDetailsFragment.java b/app/src/main/java/com/google/reviewit/PagedChangeDetailsFragment.java
new file mode 100644
index 0000000..7909695
--- /dev/null
+++ b/app/src/main/java/com/google/reviewit/PagedChangeDetailsFragment.java
@@ -0,0 +1,91 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.reviewit;
+
+import android.os.Bundle;
+import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.PagerTabStrip;
+import android.support.v4.view.ViewPager;
+
+import com.google.reviewit.app.Change;
+import com.google.reviewit.widget.ChangeEntry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class PagedChangeDetailsFragment extends BaseFragment {
+
+ @Override
+ protected @LayoutRes
+ int getLayout() {
+ return R.layout.content_paged_change_details;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ ((MainActivity) getActivity()).getSupportActionBar().hide();
+
+ init();
+ }
+
+ private void init() {
+ Change change = getApp().getQueryHandler().getCurrentChange();
+ checkArgument(change != null, "No change to display");
+
+ ChangeEntry changeEntry = new ChangeEntry(getContext());
+ changeEntry.init(getApp(), change);
+ vg(R.id.changeHeader).addView(changeEntry);
+
+ final List<PageFragment> fragments = new ArrayList<>();
+
+ CommitMessageFragment commitMessageFragment = new CommitMessageFragment();
+ commitMessageFragment.setChange(change);
+ fragments.add(commitMessageFragment);
+
+ FileListFragment fileListFragment = new FileListFragment();
+ fileListFragment.setChange(change);
+ fragments.add(fileListFragment);
+
+ // TODO add more tabs, e.g. for change messages, approvals and post review
+
+ ((ViewPager) v(R.id.pager)).setAdapter(
+ new FragmentPagerAdapter(getChildFragmentManager()) {
+ @Override
+ public Fragment getItem(int position) {
+ return fragments.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return fragments.size();
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return getString(fragments.get(position).getTitle());
+ }
+ });
+
+ PagerTabStrip pagerTabStrip = (PagerTabStrip) v(R.id.tabStrip);
+ pagerTabStrip.setDrawFullUnderline(true);
+ pagerTabStrip.setTabIndicatorColorResource(R.color.tab);
+ }
+}
diff --git a/app/src/main/java/com/google/reviewit/PostReviewFragment.java b/app/src/main/java/com/google/reviewit/PostReviewFragment.java
index bb431db..dba09c7 100644
--- a/app/src/main/java/com/google/reviewit/PostReviewFragment.java
+++ b/app/src/main/java/com/google/reviewit/PostReviewFragment.java
@@ -71,7 +71,7 @@
int vote = getArguments().getInt(VOTE);
update(vote);
- Change change = getApp().getSortActionHandler().getCurrentChange();
+ Change change = getApp().getCurrentChange();
setTitle(getString(R.string.detailed_change_title, change.info._number));
init(change);
diff --git a/app/src/main/java/com/google/reviewit/RestoreFragment.java b/app/src/main/java/com/google/reviewit/RestoreFragment.java
index 45d398a..abd107b 100644
--- a/app/src/main/java/com/google/reviewit/RestoreFragment.java
+++ b/app/src/main/java/com/google/reviewit/RestoreFragment.java
@@ -14,10 +14,10 @@
package com.google.reviewit;
-import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
import android.view.View;
import com.google.gerrit.extensions.restapi.RestApiException;
diff --git a/app/src/main/java/com/google/reviewit/ReviewChangesFragment.java b/app/src/main/java/com/google/reviewit/ReviewChangesFragment.java
index 8966c64..190eb4f 100644
--- a/app/src/main/java/com/google/reviewit/ReviewChangesFragment.java
+++ b/app/src/main/java/com/google/reviewit/ReviewChangesFragment.java
@@ -198,9 +198,7 @@
changeList.removeAllViews();
}
for (Change change : changeListData.changeList) {
- ChangeEntry changeEntry = new ChangeEntry(getContext());
- changeEntry.init(getApp(), change);
- changeList.addView(changeEntry);
+ changeList.addView(createChangeEntry(change));
addSeparator(changeList);
}
} else {
@@ -217,13 +215,25 @@
((SwipeRefreshLayout) v(R.id.swipeRefreshLayout)).setRefreshing(false);
ViewGroup changeList = vg(R.id.changeList);
for (Change change : changes) {
- ChangeEntry changeEntry = new ChangeEntry(getContext());
- changeEntry.init(ReviewChangesFragment.this, getApp(), change);
- changeList.addView(changeEntry);
+ changeList.addView(createChangeEntry(change));
addSeparator(changeList);
}
}
+ private ChangeEntry createChangeEntry(final Change change) {
+ ChangeEntry changeEntry = new ChangeEntry(getContext());
+ changeEntry.init(getApp(), change);
+
+ changeEntry.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getApp().getQueryHandler().setCurrentChange(change);
+ display(PagedChangeDetailsFragment.class);
+ }
+ });
+ return changeEntry;
+ }
+
private void addSeparator(ViewGroup viewGroup) {
View separator = new View(getContext());
separator.setLayoutParams(
diff --git a/app/src/main/java/com/google/reviewit/ServerSettingsFragment.java b/app/src/main/java/com/google/reviewit/ServerSettingsFragment.java
index 8ac0204..52c5532 100644
--- a/app/src/main/java/com/google/reviewit/ServerSettingsFragment.java
+++ b/app/src/main/java/com/google/reviewit/ServerSettingsFragment.java
@@ -15,7 +15,6 @@
package com.google.reviewit;
import android.app.AlertDialog;
-import android.app.Fragment;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
@@ -25,6 +24,7 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
diff --git a/app/src/main/java/com/google/reviewit/UnifiedDiffFragment.java b/app/src/main/java/com/google/reviewit/UnifiedDiffFragment.java
index 4a31052..8607b7e 100644
--- a/app/src/main/java/com/google/reviewit/UnifiedDiffFragment.java
+++ b/app/src/main/java/com/google/reviewit/UnifiedDiffFragment.java
@@ -84,7 +84,7 @@
? getArguments().getString(PATH)
: null;
- Change change = getApp().getSortActionHandler().getCurrentChange();
+ Change change = getApp().getCurrentChange();
checkState(change != null, "Change not set");
Map<String, FileInfo> files = change.currentRevision().files;
root = (ScrollWithHeadingsView) v(R.id.unifiedDiffRoot);
diff --git a/app/src/main/java/com/google/reviewit/app/QueryHandler.java b/app/src/main/java/com/google/reviewit/app/QueryHandler.java
index 03f60ca..7f7e0f5 100644
--- a/app/src/main/java/com/google/reviewit/app/QueryHandler.java
+++ b/app/src/main/java/com/google/reviewit/app/QueryHandler.java
@@ -50,6 +50,8 @@
*/
private boolean more = true;
+ private Change currentChange;
+
QueryHandler(ConfigManager cfgManager, Gerrit gerrit) {
this.gerrit = gerrit;
this.config = cfgManager.getQueryConfig();
@@ -110,10 +112,19 @@
: false);
}
+ public Change getCurrentChange() {
+ return currentChange;
+ }
+
+ public void setCurrentChange(Change currentChange) {
+ this.currentChange = currentChange;
+ }
+
public void reset() {
result.clear();
start = 0;
more = true;
page = 0;
+ currentChange = null;
}
}
diff --git a/app/src/main/java/com/google/reviewit/app/ReviewItApp.java b/app/src/main/java/com/google/reviewit/app/ReviewItApp.java
index b2efb88..3c1a88b 100644
--- a/app/src/main/java/com/google/reviewit/app/ReviewItApp.java
+++ b/app/src/main/java/com/google/reviewit/app/ReviewItApp.java
@@ -16,8 +16,9 @@
import android.app.Activity;
import android.app.Application;
-import android.app.FragmentManager;
import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
import android.util.Log;
import com.google.gerrit.extensions.api.GerritApi;
@@ -40,7 +41,7 @@
private Gerrit gerrit;
private PreferenceManager prefManager;
private AccountInfo self;
- private Activity currentActivity;
+ private FragmentActivity currentActivity;
@Override
public void onCreate() {
@@ -48,7 +49,7 @@
@Override
public void onActivityCreated(
Activity activity, Bundle savedInstanceState) {
- currentActivity = activity;
+ currentActivity = (FragmentActivity) activity;
}
@Override
@@ -85,7 +86,7 @@
Log.e(TAG, "Application failure", t);
if (currentActivity != null) {
FragmentManager fragmentManager =
- currentActivity.getFragmentManager();
+ currentActivity.getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.mainFrame, ErrorFragment.create(t))
.commit();
@@ -162,4 +163,14 @@
}
return self;
}
+
+ public Change getCurrentChange() {
+ switch (getPrefs().startScreen) {
+ case REVIEW_SCREEN:
+ return getQueryHandler().getCurrentChange();
+ case SORT_SCREEN:
+ default:
+ return getSortActionHandler().getCurrentChange();
+ }
+ }
}
diff --git a/app/src/main/java/com/google/reviewit/widget/FileEntry.java b/app/src/main/java/com/google/reviewit/widget/FileEntry.java
new file mode 100644
index 0000000..cfe19b1
--- /dev/null
+++ b/app/src/main/java/com/google/reviewit/widget/FileEntry.java
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.reviewit.widget;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.google.gerrit.extensions.common.FileInfo;
+import com.google.reviewit.BaseFragment;
+import com.google.reviewit.R;
+import com.google.reviewit.UnifiedDiffFragment;
+import com.google.reviewit.util.FormatUtil;
+
+public class FileEntry extends LinearLayout {
+ public FileEntry(Context context) {
+ this(context, null, 0);
+ }
+
+ public FileEntry(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public FileEntry(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ inflate(context, R.layout.file_entry, this);
+ }
+
+ public void init(
+ final BaseFragment fragment, final String path, FileInfo file) {
+ TextView pathText = ((TextView) findViewById(R.id.path));
+ pathText.setText(path);
+ pathText.setPaintFlags(
+ pathText.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+ pathText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ fragment.display(UnifiedDiffFragment.create(path));
+ }
+ });
+
+ ((TextView)findViewById(R.id.fileStatus))
+ .setText(file.status != null ? Character.toString(file.status) : "M");
+
+ ((TextView)findViewById(R.id.fileSize))
+ .setText(FormatUtil.formatBytes(file.size));
+ }
+}
diff --git a/app/src/main/res/layout/content_commit_message.xml b/app/src/main/res/layout/content_commit_message.xml
new file mode 100644
index 0000000..be741f9
--- /dev/null
+++ b/app/src/main/res/layout/content_commit_message.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="8dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:paddingTop="8dp">
+
+ <ScrollView
+ android:id="@+id/scrollView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/subject"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:typeface="monospace"
+ android:textSize="14sp"
+ android:textStyle="bold"
+ android:layout_marginBottom="8dp"/>
+
+ <TextView
+ android:id="@+id/commitMessage"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:typeface="monospace"
+ android:textSize="12sp"
+ android:textColorLink="@color/hyperlink"/>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
diff --git a/app/src/main/res/layout/content_file_list.xml b/app/src/main/res/layout/content_file_list.xml
new file mode 100644
index 0000000..f460201
--- /dev/null
+++ b/app/src/main/res/layout/content_file_list.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ScrollView
+ android:id="@+id/scrollView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:id="@+id/fileList"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
diff --git a/app/src/main/res/layout/content_paged_change_details.xml b/app/src/main/res/layout/content_paged_change_details.xml
new file mode 100644
index 0000000..c3db768
--- /dev/null
+++ b/app/src/main/res/layout/content_paged_change_details.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:id="@+id/changeHeader"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <View
+ android:background="@color/tab"
+ android:layout_height="1dp"
+ android:layout_width="match_parent"/>
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/pager"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <android.support.v4.view.PagerTabStrip
+ android:id="@+id/tabStrip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingBottom="4dp"
+ android:paddingTop="4dp"
+ android:textColor="@color/tab"
+ android:textAppearance="@style/PagerTabStripText"
+ android:background="@color/tabBackground"/>
+ </android.support.v4.view.ViewPager>
+</LinearLayout>
diff --git a/app/src/main/res/layout/file_entry.xml b/app/src/main/res/layout/file_entry.xml
new file mode 100644
index 0000000..023800c
--- /dev/null
+++ b/app/src/main/res/layout/file_entry.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <View
+ android:background="@color/separator"
+ android:layout_height="match_parent"
+ android:layout_width="1dp"/>
+
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="3dp"
+ android:paddingTop="3dp"
+ android:paddingRight="3dp"
+ android:paddingBottom="3dp"
+ android:stretchColumns="1"
+ android:shrinkColumns="1">
+
+ <TableRow>
+ <TextView
+ android:id="@+id/fileStatus"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="11sp"
+ android:layout_marginEnd="4dp"/>
+
+ <TextView
+ android:id="@+id/path"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/hyperlink"
+ android:textSize="11sp"
+ android:layout_marginEnd="4dp"/>
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <TextView
+ android:id="@+id/fileSize"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="11sp"/>
+ </TableRow>
+ </TableLayout>
+
+ <View
+ android:background="@color/separator"
+ android:layout_height="match_parent"
+ android:layout_width="1dp"/>
+</LinearLayout>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index ae4b300..bf214cc 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -84,6 +84,8 @@
<color name="separator">@android:color/darker_gray</color>
<color name="statusFailed">#910022</color>
<color name="statusOk">#009122</color>
+ <color name="tab">#3863F2</color>
+ <color name="tabBackground">#e9efff</color>
<color name="text">#000</color>
<color name="text_disabeled">#BBB</color>
<color name="transparent">#00000000</color>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c4de3bc..08a5cc4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -247,6 +247,12 @@
<string name="review_error">Posting review failed with %1$d %2$s</string>
<string name="submit_error">Submit failed with %1$d %2$s</string>
+ <!-- CommitMessageFragment -->
+ <string name="commit_message_title">Commit Message</string>
+
+ <!-- FileListFragment -->
+ <string name="file_list_title">Files</string>
+
<!-- RelativeDateFormatter -->
<string name="in_the_future">in the future</string>
<string name="month">m</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 230b562..c73fc61 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -27,4 +27,9 @@
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
+ <style name="PagerTabStripText">
+ <item name="android:textSize">16sp</item>
+ <item name="android:textStyle">bold</item>
+ </style>
+
</resources>