mirror of
https://github.com/nextcloud/android.git
synced 2024-11-27 09:39:25 +03:00
Reworked the text file preview system to avoid UI freezes with large text files
This commit is contained in:
parent
7cc88a22d1
commit
ec9f1c7eb8
3 changed files with 135 additions and 40 deletions
|
@ -5,25 +5,19 @@
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginEnd="8dp">
|
android:layout_marginEnd="8dp">
|
||||||
|
|
||||||
<ScrollView
|
<ListView
|
||||||
android:id="@+id/text_scrollview"
|
android:id="@+id/text_preview_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:scrollbars="vertical"
|
android:visibility="gone"
|
||||||
android:fillViewport="true"
|
android:divider="@null"
|
||||||
android:visibility="gone">
|
android:dividerHeight="0dp"
|
||||||
|
android:focusable="false"
|
||||||
<TextView
|
android:focusableInTouchMode="false" />
|
||||||
android:id="@+id/text_preview"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center" />
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progress_bar"
|
android:id="@+id/progress_bar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center" />
|
||||||
android:visibility="gone" />
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
24
res/layout/text_file_preview_list_item.xml
Normal file
24
res/layout/text_file_preview_list_item.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
ownCloud Android client application
|
||||||
|
|
||||||
|
Copyright (C) 2012-2013 ownCloud Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License version 2,
|
||||||
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/text_preview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:layout_gravity="center" />
|
|
@ -1,13 +1,15 @@
|
||||||
package com.owncloud.android.ui.preview;
|
package com.owncloud.android.ui.preview;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.ScrollView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.actionbarsherlock.view.Menu;
|
import com.actionbarsherlock.view.Menu;
|
||||||
|
@ -26,6 +28,8 @@ import java.io.BufferedWriter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class PreviewTextFragment extends FileFragment {
|
public class PreviewTextFragment extends FileFragment {
|
||||||
|
@ -34,9 +38,8 @@ public class PreviewTextFragment extends FileFragment {
|
||||||
private static final String TAG = PreviewTextFragment.class.getSimpleName();
|
private static final String TAG = PreviewTextFragment.class.getSimpleName();
|
||||||
|
|
||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private TextView mTextPreview;
|
private ListView mTextPreviewList;
|
||||||
private ProgressBar mProgressBar;
|
private ProgressBar mProgressBar;
|
||||||
private ScrollView mScrollView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an empty fragment for previews.
|
* Creates an empty fragment for previews.
|
||||||
|
@ -64,8 +67,8 @@ public class PreviewTextFragment extends FileFragment {
|
||||||
|
|
||||||
View ret = inflater.inflate(R.layout.text_file_preview, container, false);
|
View ret = inflater.inflate(R.layout.text_file_preview, container, false);
|
||||||
|
|
||||||
mScrollView = (ScrollView) ret.findViewById(R.id.text_scrollview);
|
mTextPreviewList = (ListView) ret.findViewById(R.id.text_preview_list);
|
||||||
mTextPreview = (TextView) ret.findViewById(R.id.text_preview);
|
mTextPreviewList.setAdapter(new TextLineAdapter());
|
||||||
mProgressBar = (ProgressBar) ret.findViewById(R.id.progress_bar);
|
mProgressBar = (ProgressBar) ret.findViewById(R.id.progress_bar);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -118,44 +121,41 @@ public class PreviewTextFragment extends FileFragment {
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
Log_OC.e(TAG, "onStart");
|
Log_OC.e(TAG, "onStart");
|
||||||
|
|
||||||
loadAndShowTextPreview(getFile().getStoragePath(), mTextPreview);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAndShowTextPreview(String location, TextView textView) {
|
private void loadAndShowTextPreview() {
|
||||||
new TextLoadAsyncTask().execute(location, textView);
|
new TextLoadAsyncTask().execute(getFile().getStoragePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the file to preview and shows its contents. Too critical to be anonymous.
|
* Reads the file to preview and shows its contents. Too critical to be anonymous.
|
||||||
*/
|
*/
|
||||||
private class TextLoadAsyncTask extends AsyncTask<Object, Void, StringWriter> {
|
private class TextLoadAsyncTask extends AsyncTask<Object, StringWriter, Void> {
|
||||||
TextView mTextView;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
mProgressBar.setVisibility(View.VISIBLE);
|
((TextLineAdapter) mTextPreviewList.getAdapter()).clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected StringWriter doInBackground(java.lang.Object... params) {
|
protected Void doInBackground(java.lang.Object... params) {
|
||||||
if (params.length != 2)
|
if (params.length != 1)
|
||||||
throw new IllegalArgumentException("The parameters to " + TextLoadAsyncTask.class.getName() + " must be (1) the file location and (2) the text view to update");
|
throw new IllegalArgumentException("The parameter to " + TextLoadAsyncTask.class.getName() + " must be the file location only");
|
||||||
final String location = (String) params[0];
|
final String location = (String) params[0];
|
||||||
mTextView = (TextView) params[1];
|
|
||||||
|
|
||||||
FileInputStream inputStream = null;
|
FileInputStream inputStream = null;
|
||||||
Scanner sc = null;
|
Scanner sc = null;
|
||||||
StringWriter source = new StringWriter();
|
|
||||||
BufferedWriter bufferedWriter = new BufferedWriter(source);
|
|
||||||
try {
|
try {
|
||||||
inputStream = new FileInputStream(location);
|
inputStream = new FileInputStream(location);
|
||||||
sc = new Scanner(inputStream);
|
sc = new Scanner(inputStream);
|
||||||
while (sc.hasNextLine()) {
|
while (sc.hasNextLine()) {
|
||||||
bufferedWriter.append(sc.nextLine());
|
StringWriter target = new StringWriter();
|
||||||
if (sc.hasNextLine()) bufferedWriter.append("\n");
|
BufferedWriter bufferedWriter = new BufferedWriter(target);
|
||||||
|
if (sc.hasNextLine())
|
||||||
|
bufferedWriter.write(sc.nextLine());
|
||||||
|
bufferedWriter.close();
|
||||||
|
publishProgress(target);
|
||||||
}
|
}
|
||||||
bufferedWriter.close();
|
|
||||||
IOException exc = sc.ioException();
|
IOException exc = sc.ioException();
|
||||||
if (exc != null) throw exc;
|
if (exc != null) throw exc;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -172,15 +172,90 @@ public class PreviewTextFragment extends FileFragment {
|
||||||
sc.close();
|
sc.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return source;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(final StringWriter stringWriter) {
|
protected void onProgressUpdate(StringWriter... values) {
|
||||||
super.onPostExecute(stringWriter);
|
super.onProgressUpdate(values);
|
||||||
|
//Using a ListView allows to show large text without the UI freeze that happens
|
||||||
|
//when calling TextView#setText() with a large CharSequence
|
||||||
|
((TextLineAdapter) mTextPreviewList.getAdapter()).add(values[0].toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid) {
|
||||||
|
super.onPostExecute(aVoid);
|
||||||
mProgressBar.setVisibility(View.GONE);
|
mProgressBar.setVisibility(View.GONE);
|
||||||
mScrollView.setVisibility(View.VISIBLE);
|
mTextPreviewList.setVisibility(View.VISIBLE);
|
||||||
mTextView.setText(new String(stringWriter.getBuffer()));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TextLineAdapter extends BaseAdapter {
|
||||||
|
private static final int LIST_ITEM_LAYOUT = R.layout.text_file_preview_list_item;
|
||||||
|
private final List<String> items = new ArrayList<>();
|
||||||
|
|
||||||
|
private void add(String line) {
|
||||||
|
items.add(line);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear() {
|
||||||
|
items.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return items.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItem(int position) {
|
||||||
|
if (position >= items.size())
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
return items.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ViewHolder viewHolder;
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView =
|
||||||
|
((LayoutInflater) getActivity().getApplicationContext()
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
|
||||||
|
.inflate(
|
||||||
|
LIST_ITEM_LAYOUT, null);
|
||||||
|
viewHolder = new ViewHolder();
|
||||||
|
viewHolder.setLineView((TextView) convertView.findViewById(R.id.text_preview));
|
||||||
|
convertView.setTag(viewHolder);
|
||||||
|
} else {
|
||||||
|
viewHolder = (ViewHolder) convertView.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
viewHolder.getLineView().setText(items.get(position));
|
||||||
|
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ViewHolder {
|
||||||
|
private TextView lineView;
|
||||||
|
|
||||||
|
private ViewHolder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getLineView() {
|
||||||
|
return lineView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineView(TextView lineView) {
|
||||||
|
this.lineView = lineView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +375,8 @@ public class PreviewTextFragment extends FileFragment {
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Log_OC.e(TAG, "onResume");
|
Log_OC.e(TAG, "onResume");
|
||||||
|
|
||||||
|
loadAndShowTextPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue