#81: Android: Display dublincore metadata

This commit is contained in:
jendib 2016-05-15 19:50:12 +02:00
parent cbc4bbb818
commit ce0678784b
No known key found for this signature in database
GPG Key ID: 06EE7F699579166F
8 changed files with 670 additions and 247 deletions

View File

@ -50,9 +50,9 @@ android {
dependencies { dependencies {
compile fileTree(dir: 'libs', include: '*.jar') compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:23.3.0' compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:design:23.3.0' compile 'com.android.support:design:23.4.0'
compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5' compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5'
compile 'org.greenrobot:eventbus:3.0.0' compile 'org.greenrobot:eventbus:3.0.0'
compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.squareup.picasso:picasso:2.5.2'

View File

@ -16,6 +16,7 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.text.method.LinkMovementMethod;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -51,7 +52,7 @@ import com.sismics.docs.resource.FileResource;
import com.sismics.docs.service.FileUploadService; import com.sismics.docs.service.FileUploadService;
import com.sismics.docs.util.NetworkUtil; import com.sismics.docs.util.NetworkUtil;
import com.sismics.docs.util.PreferenceUtil; import com.sismics.docs.util.PreferenceUtil;
import com.sismics.docs.util.TagUtil; import com.sismics.docs.util.SpannableUtil;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
@ -176,9 +177,11 @@ public class DocumentViewActivity extends AppCompatActivity {
} }
// Fill the layout // Fill the layout
// Create date
TextView createdDateTextView = (TextView) findViewById(R.id.createdDateTextView); TextView createdDateTextView = (TextView) findViewById(R.id.createdDateTextView);
createdDateTextView.setText(date); createdDateTextView.setText(date);
// Description
TextView descriptionTextView = (TextView) findViewById(R.id.descriptionTextView); TextView descriptionTextView = (TextView) findViewById(R.id.descriptionTextView);
if (description.isEmpty() || document.isNull("description")) { if (description.isEmpty() || document.isNull("description")) {
descriptionTextView.setVisibility(View.GONE); descriptionTextView.setVisibility(View.GONE);
@ -187,17 +190,20 @@ public class DocumentViewActivity extends AppCompatActivity {
descriptionTextView.setText(description); descriptionTextView.setText(description);
} }
// Tags
TextView tagTextView = (TextView) findViewById(R.id.tagTextView); TextView tagTextView = (TextView) findViewById(R.id.tagTextView);
if (tags.length() == 0) { if (tags.length() == 0) {
tagTextView.setVisibility(View.GONE); tagTextView.setVisibility(View.GONE);
} else { } else {
tagTextView.setVisibility(View.VISIBLE); tagTextView.setVisibility(View.VISIBLE);
tagTextView.setText(TagUtil.buildSpannable(tags)); tagTextView.setText(SpannableUtil.buildSpannableTags(tags));
} }
// Language
ImageView languageImageView = (ImageView) findViewById(R.id.languageImageView); ImageView languageImageView = (ImageView) findViewById(R.id.languageImageView);
languageImageView.setImageResource(getResources().getIdentifier(language, "drawable", getPackageName())); languageImageView.setImageResource(getResources().getIdentifier(language, "drawable", getPackageName()));
// Shared status
ImageView sharedImageView = (ImageView) findViewById(R.id.sharedImageView); ImageView sharedImageView = (ImageView) findViewById(R.id.sharedImageView);
sharedImageView.setVisibility(shared ? View.VISIBLE : View.GONE); sharedImageView.setVisibility(shared ? View.VISIBLE : View.GONE);
@ -679,10 +685,54 @@ public class DocumentViewActivity extends AppCompatActivity {
startActivity(intent); startActivity(intent);
} }
}); });
// Contributors
TextView contributorsTextView = (TextView) findViewById(R.id.contributorsTextView);
contributorsTextView.setText(SpannableUtil.buildSpannableContributors(document.optJSONArray("contributors")));
// Relations
JSONArray relations = document.optJSONArray("relations");
if (relations.length() > 0) {
TextView relationsTextView = (TextView) findViewById(R.id.relationsTextView);
relationsTextView.setMovementMethod(LinkMovementMethod.getInstance());
relationsTextView.setText(SpannableUtil.buildSpannableRelations(relations));
} else {
findViewById(R.id.relationsLayout).setVisibility(View.GONE);
}
// Additional dublincore metadata
displayDublincoreMetadata(R.id.subjectTextView, R.id.subjectLayout, "subject");
displayDublincoreMetadata(R.id.identifierTextView, R.id.identifierLayout, "identifier");
displayDublincoreMetadata(R.id.publisherTextView, R.id.publisherLayout, "publisher");
displayDublincoreMetadata(R.id.formatTextView, R.id.formatLayout, "format");
displayDublincoreMetadata(R.id.sourceTextView, R.id.sourceLayout, "source");
displayDublincoreMetadata(R.id.typeTextView, R.id.typeLayout, "type");
displayDublincoreMetadata(R.id.coverageTextView, R.id.coverageLayout, "coverage");
displayDublincoreMetadata(R.id.rightsTextView, R.id.rightsLayout, "rights");
} }
}); });
} }
/**
* Display a dublincore metadata.
*
* @param textViewId TextView ID
* @param blockViewId View ID
* @param name Name
*/
private void displayDublincoreMetadata(int textViewId, int blockViewId, String name) {
if (document == null) return;
String value = document.optString(name);
if (document.isNull(name) || value.isEmpty()) {
findViewById(blockViewId).setVisibility(View.GONE);
return;
}
findViewById(blockViewId).setVisibility(View.VISIBLE);
TextView textView = (TextView) findViewById(textViewId);
textView.setText(value);
}
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
switch (view.getId()) { switch (view.getId()) {

View File

@ -9,7 +9,7 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.sismics.docs.R; import com.sismics.docs.R;
import com.sismics.docs.util.TagUtil; import com.sismics.docs.util.SpannableUtil;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
@ -69,7 +69,7 @@ public class DocListAdapter extends RecyclerView.Adapter<DocListAdapter.ViewHold
holder.titleTextView.setText(document.optString("title")); holder.titleTextView.setText(document.optString("title"));
JSONArray tags = document.optJSONArray("tags"); JSONArray tags = document.optJSONArray("tags");
holder.subtitleTextView.setText(TagUtil.buildSpannable(tags)); holder.subtitleTextView.setText(SpannableUtil.buildSpannableTags(tags));
String date = DateFormat.getDateFormat(holder.dateTextView.getContext()).format(new Date(document.optLong("create_date"))); String date = DateFormat.getDateFormat(holder.dateTextView.getContext()).format(new Date(document.optLong("create_date")));
holder.dateTextView.setText(date); holder.dateTextView.setText(date);

View File

@ -0,0 +1,33 @@
package com.sismics.docs.ui.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
/**
* Non-scrollable ListView.
* All items are visible from the start.
*
* @author http://stackoverflow.com/questions/18813296/non-scrollable-listview-inside-scrollview/24629341#24629341
*/
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}

View File

@ -0,0 +1,85 @@
package com.sismics.docs.util;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Utility class for tags.
*
* @author bgamard.
*/
public class SpannableUtil {
/**
* Create a colored spannable from tags.
*
* @param tags Tags
* @return Colored spannable
*/
public static Spannable buildSpannableTags(JSONArray tags) {
return buildSpannable(tags, "name", "color");
}
/**
* Create a spannable for contributors.
*
* @param contributors Contributors
* @return Spannable
*/
public static Spannable buildSpannableContributors(JSONArray contributors) {
return buildSpannable(contributors, "username", null);
}
/**
* Create a spannable for relations.
*
* @param relations Relations
* @return Spannable
*/
public static Spannable buildSpannableRelations(JSONArray relations) {
return buildSpannable(relations, "title", null);
}
/**
* Create a spannable from a JSONArray.
*
* @param array JSONArray
* @param valueName Name of the value part
* @param colorName Name of the color part (optional)
* @return Spannable
*/
private static Spannable buildSpannable(JSONArray array, String valueName, String colorName) {
SpannableStringBuilder builder = new SpannableStringBuilder();
for (int i = 0; i < array.length(); i++) {
final JSONObject tag = array.optJSONObject(i);
int start = builder.length();
builder.append(" ").append(tag.optString(valueName)).append(" ");
builder.setSpan(new ForegroundColorSpan(Color.WHITE), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new BackgroundColorSpan(Color.parseColor(tag.optString(colorName, "#5bc0de"))), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
/*
TODO : Make tags, relations and contributors clickable
builder.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(Color.WHITE);
ds.setUnderlineText(false);
}
}, start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);*/
builder.append(" ");
}
return builder;
}
}

View File

@ -1,39 +0,0 @@
package com.sismics.docs.util;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Utility class for tags.
*
* @author bgamard.
*/
public class TagUtil {
/**
* Create a colored spannable from tags.
*
* @param tags Tags
* @return Colored spannable
*/
public static Spannable buildSpannable(JSONArray tags) {
SpannableStringBuilder builder = new SpannableStringBuilder();
for (int i = 0; i < tags.length(); i++) {
JSONObject tag = tags.optJSONObject(i);
int start = builder.length();
builder.append(" ").append(tag.optString("name")).append(" ");
builder.setSpan(new ForegroundColorSpan(Color.WHITE), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new BackgroundColorSpan(Color.parseColor(tag.optString("color"))), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append(" ");
}
return builder;
}
}

View File

@ -142,15 +142,19 @@
<!-- Right drawer --> <!-- Right drawer -->
<LinearLayout <ScrollView
android:id="@+id/right_drawer" android:id="@+id/right_drawer"
android:layout_width="300dp" android:layout_width="300dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="end"
android:orientation="vertical"
android:clickable="true" android:clickable="true"
android:background="#fff" android:background="#fff"
android:elevation="5dp"> android:elevation="5dp"
android:layout_gravity="end">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Actions --> <!-- Actions -->
@ -285,6 +289,8 @@
android:id="@+id/createdDateTextView" android:id="@+id/createdDateTextView"
android:layout_toRightOf="@id/createdDateLabel" android:layout_toRightOf="@id/createdDateLabel"
android:layout_toEndOf="@id/createdDateLabel" android:layout_toEndOf="@id/createdDateLabel"
android:layout_toLeftOf="@id/sharedImageView"
android:layout_toStartOf="@id/sharedImageView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="24dp" android:layout_height="24dp"
android:gravity="center_vertical" android:gravity="center_vertical"
@ -332,6 +338,7 @@
android:fontFamily="sans-serif-light"/> android:fontFamily="sans-serif-light"/>
<ImageView <ImageView
android:contentDescription="@string/shared"
android:id="@+id/sharedImageView" android:id="@+id/sharedImageView"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
@ -343,6 +350,7 @@
android:layout_toStartOf="@+id/languageImageView"/> android:layout_toStartOf="@+id/languageImageView"/>
<ImageView <ImageView
android:contentDescription="@string/language"
android:id="@+id/languageImageView" android:id="@+id/languageImageView"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
@ -352,6 +360,278 @@
</RelativeLayout> </RelativeLayout>
<!-- Additional dublincore metadata -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingBottom="12dp">
<!-- Subject -->
<LinearLayout
android:id="@+id/subjectLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/subject"/>
<TextView
android:id="@+id/subjectTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Identifier -->
<LinearLayout
android:id="@+id/identifierLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/identifier"/>
<TextView
android:id="@+id/identifierTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Publisher -->
<LinearLayout
android:id="@+id/publisherLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/publisher"/>
<TextView
android:id="@+id/publisherTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Format -->
<LinearLayout
android:id="@+id/formatLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/format"/>
<TextView
android:id="@+id/formatTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Source -->
<LinearLayout
android:id="@+id/sourceLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/source"/>
<TextView
android:id="@+id/sourceTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Type -->
<LinearLayout
android:id="@+id/typeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/type"/>
<TextView
android:id="@+id/typeTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Coverage -->
<LinearLayout
android:id="@+id/coverageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/coverage"/>
<TextView
android:id="@+id/coverageTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Rights -->
<LinearLayout
android:id="@+id/rightsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/rights"/>
<TextView
android:id="@+id/rightsTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Contributors -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/contributors"/>
<TextView
android:id="@+id/contributorsTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
<!-- Relations -->
<LinearLayout
android:id="@+id/relationsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="2dp">
<TextView
android:layout_weight="0.33"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:fontFamily="sans-serif"
android:text="@string/relations"/>
<TextView
android:id="@+id/relationsTextView"
android:layout_weight="0.67"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"/>
</LinearLayout>
</LinearLayout>
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
@ -369,14 +649,16 @@
android:text="@string/who_can_access" android:text="@string/who_can_access"
android:layout_margin="12dp"/> android:layout_margin="12dp"/>
<ListView <com.sismics.docs.ui.view.NonScrollListView
android:id="@+id/aclListView" android:id="@+id/aclListView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:choiceMode="singleChoice" android:choiceMode="singleChoice"
android:divider="@android:color/transparent" android:divider="@android:color/transparent"
android:dividerHeight="0dp"/> android:dividerHeight="0dp"/>
</LinearLayout> </LinearLayout>
</ScrollView>
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>

View File

@ -132,5 +132,17 @@
<string name="storage_quota">Storage quota</string> <string name="storage_quota">Storage quota</string>
<string name="storage_display">%1$d/%2$d MB</string> <string name="storage_display">%1$d/%2$d MB</string>
<string name="validation_code">Validation code</string> <string name="validation_code">Validation code</string>
<string name="shared">Shared</string>
<string name="language">Language</string>
<string name="coverage">Coverage</string>
<string name="type">Type</string>
<string name="source">Source</string>
<string name="format">Format</string>
<string name="publisher">Publisher</string>
<string name="identifier">Identifier</string>
<string name="subject">Subject</string>
<string name="rights">Rights</string>
<string name="contributors">Contributors</string>
<string name="relations">Relations</string>
</resources> </resources>