...
 
Commits (3)
package id.ac.stis.capi.lessthink.binders;
import android.view.View;
import android.widget.TextView;
import id.ac.stis.capi.R;
import me.texy.treeview.TreeNode;
import me.texy.treeview.base.BaseNodeViewBinder;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class FirstLevelNodeViewBinder extends BaseNodeViewBinder {
private TextView mainText;
public FirstLevelNodeViewBinder(View itemView) {
super(itemView);
mainText = itemView.findViewById(R.id.text_main);
}
@Override
public int getLayoutId() {
return R.layout.item_node_first;
}
@Override
public void bindView(TreeNode treeNode) {
mainText.setText(treeNode.getValue().toString());
}
}
package id.ac.stis.capi.lessthink.binders;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import id.ac.stis.capi.R;
import id.ac.stis.capi.lessthink.models.ModeTreeNode;
import me.texy.treeview.TreeNode;
import me.texy.treeview.base.BaseNodeViewBinder;
import me.texy.treeview.base.BaseNodeViewFactory;
......@@ -13,13 +19,51 @@ import me.texy.treeview.base.BaseNodeViewFactory;
public class NodeViewFactory extends BaseNodeViewFactory {
@Override
public BaseNodeViewBinder getNodeViewBinder(View view, int level) {
switch (level) {
case 0:
return new FirstLevelNodeViewBinder(view);
case 1:
return new FirstLevelNodeViewBinder(view);
default:
return null;
return new NodeViewBinder(view, level);
}
public class NodeViewBinder extends BaseNodeViewBinder {
private int level;
private TextView mainText, secondaryText;
private ImageView imageStatus;
public NodeViewBinder(View itemView, int level) {
super(itemView);
this.level = level;
this.mainText = itemView.findViewById(R.id.text_main);
this.secondaryText = itemView.findViewById(R.id.text_secondary);
this.imageStatus = itemView.findViewById(R.id.image_status);
}
@Override
public int getLayoutId() {
return R.layout.item_node_first;
}
@Override
public void bindView(TreeNode treeNode) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) itemView.getLayoutParams();
params.leftMargin = 64 * (level + 1);
params.rightMargin = 64 * (level + 1);
itemView.setLayoutParams(params);
mainText.setText(treeNode.getValue().toString());
if (treeNode instanceof ModeTreeNode) {
secondaryText.setText(((ModeTreeNode) treeNode).getValueId());
switch (((ModeTreeNode) treeNode).getMode()) {
case ModeTreeNode.DOWNLOADED:
imageStatus.setImageResource(R.drawable.ic_check_circle);
break;
case ModeTreeNode.QUEUED:
imageStatus.setImageResource(R.drawable.ic_download);
break;
}
} else {
secondaryText.setVisibility(View.GONE);
}
}
}
}
package id.ac.stis.capi.lessthink.listeners;
import java.util.List;
import id.ac.stis.capi.lessthink.models.DependencyDetails;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public interface DependenciesParserListener {
void onDependenciesParsingCompleted(List<DependencyDetails> dependencyDetails);
}
package id.ac.stis.capi.lessthink.models;
import me.texy.treeview.TreeNode;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class ModeTreeNode extends TreeNode {
public static final int DOWNLOADED = 0;
public static final int QUEUED = 1;
private int mode;
private String valueId;
public ModeTreeNode(String value, String valueId, int mode) {
super(value);
this.valueId = valueId;
this.mode = mode;
}
public String getValueId() {
return valueId;
}
public int getMode() {
return mode;
}
public void setMode(int mode) {
this.mode = mode;
}
}
package id.ac.stis.capi.lessthink.tasks;
import android.os.AsyncTask;
import java.io.File;
import java.util.List;
import id.ac.stis.capi.lessthink.listeners.DependenciesParserListener;
import id.ac.stis.capi.lessthink.models.DependencyDetails;
import id.ac.stis.capi.odk.dao.FormsDao;
import id.ac.stis.capi.odk.dto.Form;
import id.ac.stis.capi.odk.logic.FormDetails;
import id.ac.stis.capi.odk.utilities.FileUtils;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class DependenciesParserTask extends AsyncTask<FormDetails, String, List<DependencyDetails>> {
private FormsDao formsDao;
private DependenciesParserListener dependenciesParserListener;
/**
* Set the dependencies parser listener
*
* @param dependenciesParserListener listener
*/
public void setDependenciesParserListener(DependenciesParserListener
dependenciesParserListener) {
this.dependenciesParserListener = dependenciesParserListener;
}
@Override
protected List<DependencyDetails> doInBackground(FormDetails... lists) {
formsDao = new FormsDao();
FormDetails toParse = lists[0];
// FormDetails contains only some basic information.
// To get the file path, we need to get the corresponding Form
Form form = formsDao.getFormsFromCursor(formsDao.getFormsCursorForFormId(toParse.formID)).get(0);
File file = new File(form.getFormFilePath());
// Parse the dependencies and save it as a list
// return the list of dependencies parsed from the XML form definition
return FileUtils.parseFormDependencies(file);
}
@Override
protected void onPostExecute(List<DependencyDetails> result) {
super.onPostExecute(result);
if (dependenciesParserListener != null) {
dependenciesParserListener.onDependenciesParsingCompleted(result);
}
}
}
......@@ -56,9 +56,9 @@ public class DependenciesResolverTask extends AsyncTask<List<FormDetails>, Strin
// Process the forms supplied by the execute() parameter
for (FormDetails fd : toResolve) {
List<DependencyDetails> details = processOneForm(fd, total, count++);
if (details.size() > 0) {
// if (details.size() > 0) {
result.put(fd, details);
}
// }
}
return result;
......@@ -171,9 +171,9 @@ public class DependenciesResolverTask extends AsyncTask<List<FormDetails>, Strin
List<FormDetails> evaluated = evaluateOneFormDependencies(evaluateMe,
k.formName, total, count++);
if (evaluated.size() > 0) {
// if (evaluated.size() > 0) {
result.put(k, evaluated);
}
// }
}
if (listener != null) {
......
......@@ -29,6 +29,10 @@ import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
......@@ -48,6 +52,149 @@ import timber.log.Timber;
*/
public class XmlUtils {
public static boolean setValuesByMap(File file, Map<String, String> values) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(file);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
Set<String> xPathStringSet = values.keySet();
for (String xPathString : xPathStringSet) {
XPathExpression expr = xpath.compile(xPathString);
org.w3c.dom.Node node = (org.w3c.dom.Node) expr.evaluate(doc, XPathConstants.NODE);
node.setTextContent(values.get(xPathString));
}
// Commit changes
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new FileOutputStream(file));
transformer.transform(source, result);
} catch (Exception e) {
Timber.e(e);
return false;
}
return true;
}
public static Map<String, String> getInitValueRules(File file, String rootElement) {
Timber.d("Parsing dependencies from %s file", file.getAbsolutePath());
final InputStream is;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e1) {
Timber.e(e1);
throw new IllegalStateException(e1);
}
InputStreamReader isr;
try {
isr = new InputStreamReader(is, "UTF-8");
} catch (UnsupportedEncodingException uee) {
Timber.w(uee, "Trying default encoding as UTF 8 encoding unavailable");
isr = new InputStreamReader(is);
}
final Document doc;
try {
doc = XFormParser.getXMLDocument(isr);
} catch (IOException e) {
Timber.e(e, "Unable to parse XML document %s", file.getAbsolutePath());
throw new IllegalStateException("Unable to parse XML document", e);
} finally {
try {
isr.close();
} catch (IOException e) {
Timber.w("%s error closing from reader", file.getAbsolutePath());
}
}
final String html = doc.getRootElement().getNamespace();
final Element head = doc.getRootElement().getElement(html, "head");
Map<String, String> result = new HashMap<>();
Element model = getChildElement(head, "model");
List<Element> initValues = findAllElementsByAttrName(model, "initvalue");
for (Element initValue : initValues) {
String nodeset = null;
String init = null;
for (int i = 0; i < initValue.getAttributeCount(); i++) {
if (initValue.getAttributeName(i).equals("nodeset")) {
nodeset = initValue.getAttributeValue(i);
}
if (initValue.getAttributeName(i).equals("initvalue")) {
if (initValue.getAttributeValue(i).contains(rootElement)) {
init = initValue.getAttributeValue(i);
}
}
}
if (nodeset != null && init != null) {
result.put(nodeset, init);
}
}
return result;
}
public static Map<String, String> getInstanceValuesMap(File file, Map<String, String> xPaths) {
Map<String, String> values = new LinkedHashMap<>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(file);
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
Set<String> xPathsKeySet = xPaths.keySet();
for (String xPathsKey : xPathsKeySet) {
XPathExpression expression = xPath.compile(xPaths.get(xPathsKey));
Object res = expression.evaluate(doc, XPathConstants.STRING);
String node = (String) res;
values.put(xPathsKey, node);
}
} catch (Throwable throwable) {
Timber.e(throwable);
}
return values;
}
public static String getInstanceValue(File file, String xpath) {
String value = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(file);
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression expression = xPath.compile(xpath);
Object res = expression.evaluate(doc, XPathConstants.STRING);
value = (String) res;
} catch (Throwable throwable) {
Timber.e(throwable);
}
return value;
}
public static List<String> getInstanceXPathList(File file) {
InputStream is;
......@@ -141,8 +288,12 @@ public class XmlUtils {
String html = doc.getRootElement().getNamespace();
Element body = doc.getRootElement().getElement(html, "body");
List<Element> inputs = findAllElementsByTagName(body, "input");
List<Element> inputs = findAllElementsByAttrName(body, "ref");
for (Element input : inputs) {
if (input.getName().equals("group")) {
continue;
}
String ref = getAttributeValue(input, "ref");
if (ref != null) {
if (xPaths.contains(ref)) {
......@@ -153,25 +304,6 @@ public class XmlUtils {
}
}
}
// for (int i = 0; i < body.getChildCount(); i++) {
// if (body.isText(i)) {
// continue;
// }
//
// if (body.getType(i) == Node.ELEMENT) {
// Element curr = body.getElement(i);
//
// String ref = getAttributeValue(curr, "ref");
// if (ref != null) {
// if (xPaths.contains(ref)) {
// Element label = getChildElement(curr, "label");
// if (label != null) {
// titles.put(ref, getText(label));
// }
// }
// }
// }
// }
return new FormLabels(formId, titles);
}
......@@ -206,7 +338,6 @@ public class XmlUtils {
private static List<String> getXPathByElement(Element element) {
List<String> target = new ArrayList<>();
// getXPathToTarget(target, element, "/" + element.getName());
getXPathToTarget(target, element, "");
return target;
......@@ -411,6 +542,7 @@ public class XmlUtils {
if (tagName.equals(el.getName())) {
elementList.add(el);
}
for (int i = 0; i < el.getChildCount(); i++) {
if (el.getType(i) == Node.ELEMENT) {
Element elem = el.getElement(i);
......@@ -425,6 +557,7 @@ public class XmlUtils {
if (localName.equals(el.getName()) && nameSpaceURI.contains(el.getNamespace())) {
elementList.add(el);
}
for (int i = 0; i < el.getChildCount(); i++) {
if (el.getType(i) == Node.ELEMENT) {
Element elem = el.getElement(i);
......@@ -444,6 +577,7 @@ public class XmlUtils {
for (int i = 0; i < el.getAttributeCount(); i++) {
if (attrName.equals(el.getAttributeName(i))) {
elementList.add(el);
break;
}
}
......
......@@ -79,9 +79,8 @@ public class SplashScreenActivity extends AppCompatActivity {
startActivity(new Intent(this, CapiMainActivity.class));
// startActivity(new Intent(this, BSActivity.class));
} else {
startActivity(new Intent(this, CapiMainActivity.class));
// startActivity(new Intent(this, CapiLoginActivity.class));
// startActivity(new Intent(this, ListingInstanceActivity.class));
// startActivity(new Intent(this, CapiMainActivity.class));
startActivity(new Intent(this, CapiLoginActivity.class));
}
finish();
}
......
......@@ -48,6 +48,11 @@ public class CapiFormAdapter extends RecyclerView.Adapter<CapiFormAdapter.ViewHo
private Fragment fragment;
private ArrayList<HashMap<String, String>> dataSet;
private ArrayList<HashMap<String, String>> dataSetOri;
private OnFormDeletedListener onFormDeletedListener;
public void setOnFormDeletedListener(OnFormDeletedListener onFormDeletedListener) {
this.onFormDeletedListener = onFormDeletedListener;
}
public CapiFormAdapter(Activity activity, Fragment fragment) {
this.context = activity;
......@@ -118,8 +123,7 @@ public class CapiFormAdapter extends RecyclerView.Adapter<CapiFormAdapter.ViewHo
private void seeListRespons(int position) {
Intent intent;
// FIXME: 12/07/2018 INVERT! Testing purpose so added negation (!)
if (!dataSet.get(position).get(FORM_TYPE_KEY).equalsIgnoreCase(FormsProviderAPI.FORM_TYPE_UPDATING)) {
if (dataSet.get(position).get(FORM_TYPE_KEY).equalsIgnoreCase(FormsProviderAPI.FORM_TYPE_UPDATING)) {
intent = new Intent(context, ListingInstanceActivity.class);
} else {
intent = new Intent(context, CapiInstanceActivity.class);
......@@ -204,13 +208,17 @@ public class CapiFormAdapter extends RecyclerView.Adapter<CapiFormAdapter.ViewHo
deletedItems.put(HAS_BEEN_DOWNLOADED, "false");
dataSet.add(deletedItems);
notifyDataSetChanged();
if (onFormDeletedListener != null) {
onFormDeletedListener.onFormDelete(formIdKey);
}
}
private void showConfirmDelete(final int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Delete Form");
builder.setMessage("Are you sure to delete \"" + dataSet.get(position).get(FORMNAME) + "form?");
builder.setMessage("Are you sure to delete \"" + dataSet.get(position).get(FORMNAME) + "\" form?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
......@@ -290,4 +298,8 @@ public class CapiFormAdapter extends RecyclerView.Adapter<CapiFormAdapter.ViewHo
imgPattern = (ImageView) itemView.findViewById(R.id.image_pattern);
}
}
public interface OnFormDeletedListener {
void onFormDelete(String formId);
}
}
......@@ -36,8 +36,26 @@ import org.javarosa.form.api.FormEntryModel;
import org.javarosa.xform.parse.XFormParser;
import org.javarosa.xform.util.XFormUtils;
import org.javarosa.xpath.XPathTypeMismatchException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import au.com.bytecode.opencsv.CSVReader;
import id.ac.stis.capi.R;
import id.ac.stis.capi.lessthink.models.DependencyDetails;
import id.ac.stis.capi.lessthink.utils.XmlUtils;
import id.ac.stis.capi.odk.application.Collect;
import id.ac.stis.capi.odk.dao.InstancesDao;
import id.ac.stis.capi.odk.database.ItemsetDbAdapter;
import id.ac.stis.capi.odk.external.ExternalAnswerResolver;
import id.ac.stis.capi.odk.external.ExternalDataHandler;
......@@ -50,22 +68,9 @@ import id.ac.stis.capi.odk.listeners.FormLoaderListener;
import id.ac.stis.capi.odk.logic.FileReferenceFactory;
import id.ac.stis.capi.odk.logic.FormController;
import id.ac.stis.capi.odk.preferences.PreferenceKeys;
import id.ac.stis.capi.odk.provider.InstanceProviderAPI;
import id.ac.stis.capi.odk.utilities.FileUtils;
import id.ac.stis.capi.odk.utilities.ZipUtils;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import au.com.bytecode.opencsv.CSVReader;
import timber.log.Timber;
/**
......@@ -73,7 +78,7 @@ import timber.log.Timber;
*
* @author Carl Hartung (carlhartung@gmail.com)
* @author Yaw Anokwa (yanokwa@gmail.com)
* edit Mahendri Dwicahyo
* edit Mahendri Dwicahyo
*/
public class FormLoaderTask extends AsyncTask<String, String, FormLoaderTask.FECWrapper> {
private static final String ITEMSETS_CSV = "itemsets.csv";
......@@ -112,6 +117,10 @@ public class FormLoaderTask extends AsyncTask<String, String, FormLoaderTask.FEC
String formHash = FileUtils.getMd5Hash(formXml);
File formBin = new File(Collect.CACHE_PATH + File.separator + formHash + ".formdef");
publishProgress(Collect.getInstance().getString(R.string.parsing_dependencies));
resolveAndExecuteDependencies(formXml);
publishProgress(
Collect.getInstance().getString(R.string.survey_loading_reading_form_message));
......@@ -338,6 +347,33 @@ public class FormLoaderTask extends AsyncTask<String, String, FormLoaderTask.FEC
}
private void resolveAndExecuteDependencies(File file) {
List<DependencyDetails> deps = FileUtils.parseFormDependencies(file);
for (DependencyDetails dep : deps) {
File instanceFile = new File(instancePath);
String onValue = XmlUtils.getInstanceValue(instanceFile, dep.getDependencyRule());
if (onValue != null && !onValue.trim().isEmpty()) {
InstancesDao instancesDao = new InstancesDao();
Cursor c = instancesDao.getInstancesCursor(InstanceProviderAPI.InstanceColumns.INSTANCE_UUID + "=?",
new String[]{onValue});
if (c != null) {
if (c.moveToFirst()) {
String readInstanceFilePath = c.getString(c.getColumnIndex(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH));
File readInstanceFile = new File(readInstanceFilePath);
Map<String, String> initValues = XmlUtils.getInitValueRules(file, dep.getFormRootElement());
Map<String, String> initValuesValue = XmlUtils.getInstanceValuesMap(readInstanceFile, initValues);
XmlUtils.setValuesByMap(instanceFile, initValuesValue);
}
c.close();
}
}
}
}
@SuppressWarnings("unchecked")
private void loadExternalData(File mediaFolder) {
// SCTO-594
......
......@@ -535,7 +535,7 @@ public class FileUtils {
String version = dependency.getAttributeValue(null, "version");
String on = dependency.getAttributeValue(null, "on");
DependencyDetails details = new DependencyDetails(name, id, version, on);
DependencyDetails details = new DependencyDetails(id, version, name, on);
result.add(details);
}
}
......
......@@ -21,10 +21,6 @@ import android.text.format.DateFormat;
import org.kxml2.io.KXmlParser;
import org.kxml2.kdom.Document;
import id.ac.stis.capi.BuildConfig;
import id.ac.stis.capi.R;
import id.ac.stis.capi.odk.application.Collect;
import id.ac.stis.capi.odk.preferences.PreferenceKeys;
import org.opendatakit.httpclientandroidlib.Header;
import org.opendatakit.httpclientandroidlib.HttpEntity;
import org.opendatakit.httpclientandroidlib.HttpHost;
......@@ -64,6 +60,10 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import id.ac.stis.capi.BuildConfig;
import id.ac.stis.capi.R;
import id.ac.stis.capi.odk.application.Collect;
import id.ac.stis.capi.odk.preferences.PreferenceKeys;
import timber.log.Timber;
/**
......@@ -75,17 +75,14 @@ import timber.log.Timber;
*/
public final class WebUtils {
private static final String USER_AGENT_HEADER = "User-Agent";
public static final String OPEN_ROSA_VERSION_HEADER = "X-OpenRosa-Version";
public static final String OPEN_ROSA_VERSION = "1.0";
private static final String DATE_HEADER = "Date";
public static final String HTTP_CONTENT_TYPE_TEXT_XML = "text/xml";
public static final int CONNECTION_TIMEOUT = 30000;
public static final String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
public static final String GZIP_CONTENT_ENCODING = "gzip";
private static final String USER_AGENT_HEADER = "User-Agent";
private static final String DATE_HEADER = "Date";
public static final List<AuthScope> buildAuthScopes(String host) {
List<AuthScope> asList = new ArrayList<AuthScope>();
......@@ -137,7 +134,7 @@ public final class WebUtils {
* for accessing this host.
*/
public static final void addCredentials(String username, String password,
String host) {
String host) {
// to ensure that this is the only authentication available for this
// host...
clearHostCredentials(host);
......@@ -303,7 +300,7 @@ public final class WebUtils {
* http context and client objects involved in the web connection.
*/
public static DocumentFetchResult getXmlDocument(String urlString,
HttpContext localContext, HttpClient httpclient) {
HttpContext localContext, HttpClient httpclient) {
URI u = null;
try {
URL url = new URL(urlString);
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
</vector>
......@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFF"
android:fillColor="#000"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="match_parent"
android:fillViewport="true">
<!--<TextView-->
<!--android:id="@android:id/empty"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:gravity="center"-->
<!--android:text="@string/no_items_display"-->
<!--android:textSize="21sp" />-->
<ProgressBar
android:id="@+id/holder_progress_bar"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_centerInParent="true"/>
</android.support.v4.widget.NestedScrollView>
<LinearLayout
android:id="@+id/holder_message"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background"
android:orientation="vertical"
android:layout_centerInParent="true"
android:gravity="center"
android:visibility="gone">
<ImageView
android:id="@+id/icon_message"
android:layout_width="50dp"
android:layout_height="70dp"
android:tint="@android:color/darker_gray"
app:srcCompat="@drawable/ic_sad_sorry"/>
<TextView
android:id="@+id/message"
android:layout_alignParentTop="true"
android:gravity="center_horizontal"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
tools:listitem="@layout/collectiva_item_form" />
<ProgressBar
android:id="@+id/holder_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sorry, internal error."/>
android:layout_below="@+id/recycler_view"
android:layout_centerHorizontal="true"
android:layout_centerInParent="false"
android:layout_centerVertical="false"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp" />
<LinearLayout
android:id="@+id/holder_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/background"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:visibility="gone">
<ImageView
android:id="@+id/icon_message"
android:layout_width="50dp"
android:layout_height="70dp"
android:tint="@android:color/darker_gray"
app:srcCompat="@drawable/ic_sad_sorry" />
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sorry, internal error." />
</LinearLayout>
</LinearLayout>
<!--<TextView-->
<!--android:id="@android:id/empty"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:gravity="center"-->
<!--android:text="@string/no_items_display"-->
<!--android:textSize="21sp" />-->
</RelativeLayout>
\ No newline at end of file
......@@ -3,31 +3,49 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="4dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_icon"
android:id="@+id/image_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_folder" />
<TextView
android:id="@+id/text_main"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:text="TextView"
android:textAllCaps="false"
android:textStyle="bold" />
android:orientation="vertical">
<TextView
android:id="@+id/text_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:text="TextView"
android:textColor="@color/black"
android:textStyle="bold" />
<TextView
android:id="@+id/text_secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:text="TextView"
android:textSize="12sp"
android:textStyle="italic" />
</LinearLayout>
<ImageView
android:id="@+id/image_status"
android:id="@+id/image_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:srcCompat="@drawable/ic_download" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
......@@ -8,10 +7,11 @@
android:orientation="vertical"
tools:context="id.ac.stis.capi.revalidasi.activities.DataDownloadActivity">
<com.rahadi.vsen.views.ExtendedRecyclerView
<id.ac.stis.capi.lessthink.views.ExtendedRecyclerView
android:id="@+id/vd_recycler_down"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:listitem="@layout/vd_item_download" />
<LinearLayout
android:id="@+id/holder_message"
......@@ -19,20 +19,22 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="30dp"
android:orientation="vertical">
android:orientation="vertical"
android:padding="30dp">
<ImageView
android:id="@+id/icon_message"
android:layout_width="50dp"
android:layout_height="70dp"
android:tint="@android:color/darker_gray"
app:srcCompat="@drawable/ic_sad_sorry"/>
app:srcCompat="@drawable/ic_sad_sorry" />
<TextView
android:id="@+id/message_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="Sorry, internal error."/>
android:text="Sorry, internal error."
android:textAlignment="center" />
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
......@@ -531,4 +531,5 @@
<string name="access_token">pk.eyJ1Ijoia2FkZGFmaSIsImEiOiJjajMwOWlmazkwMDZmMnhvaDA5NnZzbXE0In0.Y9TXg0rJjTybmb3T-z76qw</string>
<string name="fetching_dependencies">Resolving dependencies of %1$s.\n\nForm %2$s of %3$s form(s).</string>
<string name="parsing_dependencies">Resolving dependencies…</string>
</resources>