show recordings

This commit is contained in:
Alexey Kuznetsov 2016-03-12 10:28:20 +03:00
commit 029b99852e
20 changed files with 275 additions and 104 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

View file

@ -1,6 +1,7 @@
package com.github.axet.audiorecorder.activities;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@ -11,80 +12,101 @@ import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.github.axet.audiorecorder.R;
import com.github.axet.audiorecorder.animations.RecordingAnimation;
import com.github.axet.audiorecorder.app.Storage;
public class MainActivity extends AppCompatActivity {
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
Recordings recordings = new Recordings();
public class MainActivity extends AppCompatActivity implements AbsListView.OnScrollListener{
static final int TYPE_COLLAPSED = 0;
static final int TYPE_EXPANDED = 1;
static final int TYPE_DELETED = 2;
public class Recordings implements ListAdapter {
final int[] ALL = {TYPE_COLLAPSED, TYPE_EXPANDED};
@Override
public boolean areAllItemsEnabled() {
return true;
int selected;
int scrollState;
Recordings recordings;
Storage storage;
ListView list;
public class Recordings extends ArrayAdapter<File> {
public Recordings(Context context) {
super(context, 0);
}
@Override
public boolean isEnabled(int position) {
return true;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getContext());
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.recording, parent, false);
convertView.setTag(-1);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
File f = getItem(position);
@Override
public int getCount() {
return 0;
}
TextView title = (TextView) convertView.findViewById(R.id.recording_title);
title.setText(f.getName());
@Override
public Object getItem(int position) {
return null;
}
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TextView time = (TextView) convertView.findViewById(R.id.recording_time);
time.setText(s.format(new Date(f.lastModified())));
@Override
public long getItemId(int position) {
return 0;
}
View player = convertView.findViewById(R.id.recording_player);
player.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
@Override
public boolean hasStableIds() {
return false;
}
if(selected == position) {
RecordingAnimation.apply(list, convertView, true, scrollState == SCROLL_STATE_IDLE && (int) convertView.getTag() == TYPE_COLLAPSED);
convertView.setTag(TYPE_EXPANDED);
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selected = -1;
notifyDataSetChanged();
}
});
}else {
RecordingAnimation.apply(list, convertView, false, scrollState == SCROLL_STATE_IDLE && (int) convertView.getTag() == TYPE_EXPANDED);
convertView.setTag(TYPE_COLLAPSED);
@Override
public int getItemViewType(int position) {
return 0;
}
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selected = position;
notifyDataSetChanged();
}
});
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean isEmpty() {
return getCount() == 0;
return convertView;
}
}
@ -106,8 +128,8 @@ public class MainActivity extends AppCompatActivity {
}
});
ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(recordings);
list = (ListView) findViewById(R.id.list);
list.setOnScrollListener(this);
list.setEmptyView(findViewById(R.id.empty_list));
if (permitted())
@ -116,7 +138,22 @@ public class MainActivity extends AppCompatActivity {
// load recordings
void load() {
storage = new Storage(this);
File f = storage.getStoragePath();
File[] ff = f.listFiles();
ArrayList<File> a = null;
if (ff != null) {
a = new ArrayList<File>(Arrays.asList(ff));
} else {
a = new ArrayList<File>();
}
recordings = new Recordings(this);
recordings.addAll(a);
list.setAdapter(recordings);
}
@Override
@ -145,6 +182,14 @@ public class MainActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
if (permitted(PERMISSIONS))
load();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@ -177,4 +222,13 @@ public class MainActivity extends AppCompatActivity {
}
return true;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.scrollState = scrollState;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
}

View file

@ -33,7 +33,7 @@ public class RecordingAnimation extends MarginAnimation {
}
public RecordingAnimation(ListView list, View v, boolean expand) {
super(v.findViewById(R.id.recording_detail), expand);
super(v.findViewById(R.id.recording_player), expand);
handler = new Handler();

View file

@ -10,9 +10,13 @@ import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.preference.EditTextPreference;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@ -22,9 +26,12 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import com.github.axet.audiorecorder.R;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
@ -42,7 +49,6 @@ public class OpenFileDialog extends AlertDialog.Builder {
private Drawable folderIcon;
private Drawable fileIcon;
private Drawable upIcon;
private String accessDeniedMessage;
FileAdapter adapter;
public interface OpenDialogListener {
@ -110,20 +116,20 @@ public class OpenFileDialog extends AlertDialog.Builder {
linearLayout.addView(createBackItem(context));
listView = createListView(context);
linearLayout.addView(listView);
setCustomTitle(title)
.setView(linearLayout)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (listener != null) {
if (selectedIndex > -1)
listener.onFileSelected(listView.getItemAtPosition(selectedIndex).toString());
else
listener.onFileSelected(currentPath.toString());
}
}
})
.setNegativeButton(android.R.string.cancel, null);
setCustomTitle(title);
setView(linearLayout);
setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (listener != null) {
if (selectedIndex > -1)
listener.onFileSelected(listView.getItemAtPosition(selectedIndex).toString());
else
listener.onFileSelected(currentPath.toString());
}
}
});
setNegativeButton(android.R.string.cancel, null);
}
@Override
@ -172,11 +178,6 @@ public class OpenFileDialog extends AlertDialog.Builder {
return this;
}
public OpenFileDialog setAccessDeniedMessage(String message) {
this.accessDeniedMessage = message;
return this;
}
private static Display getDefaultDisplay(Context context) {
return ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
}
@ -255,22 +256,45 @@ public class OpenFileDialog extends AlertDialog.Builder {
return ll;
}
public interface EditClick {
public void click(String text);
}
AlertDialog.Builder createEditDialog(Context context, String title, String value, final EditClick ok) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
LinearLayout ll = new LinearLayout(context);
ll.setOrientation(LinearLayout.VERTICAL);
TextView text = createTitle(context);
text.setText(title);
ll.addView(text);
final EditText input = new EditText(context);
input.setText(value);
ll.addView(input);
builder.setView(ll);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
ok.click(input.getText().toString().trim());
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
return builder;
}
private TextView createNewFolder(final Context context) {
Button textView = new Button(context);
textView.setPadding(15, 0, 15, 0);
textView.setText("New Folder");
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditTextPreference edit = new EditTextPreference(getContext());
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
final EditText input = new EditText(getContext());
builder.setView(input);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim();
AlertDialog.Builder builder = createEditDialog(context, "Folder Name", "", new EditClick() {
@Override
public void click(String value) {
File f = new File(currentPath, value);
if (!f.mkdir()) {
Toast.makeText(context, "Unable create folder: '" + value + "'", Toast.LENGTH_SHORT).show();
@ -278,11 +302,6 @@ public class OpenFileDialog extends AlertDialog.Builder {
RebuildFiles();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
builder.show();
}
});
@ -331,8 +350,46 @@ public class OpenFileDialog extends AlertDialog.Builder {
changeTitle();
}
private ListView createListView(Context context) {
public static final String RENAME = "Rename";
public static final String DELETE = "Delete";
private ListView createListView(final Context context) {
ListView listView = new ListView(context);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
PopupMenu p = new PopupMenu(context, view);
p.getMenu().add(RENAME);
p.getMenu().add(DELETE);
p.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getTitle().equals(RENAME)) {
final File ff = (File) adapter.getItem(position);
AlertDialog.Builder b = createEditDialog(context, "Folder Name", ff.getName(), new EditClick() {
@Override
public void click(String text) {
File f = new File(ff.getParent(), text);
ff.renameTo(f);
RebuildFiles();
}
});
b.show();
return true;
}
if (item.getTitle().equals(DELETE)) {
File ff = (File) adapter.getItem(position);
ff.delete();
RebuildFiles();
return true;
}
return false;
}
});
p.show();
return true;
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override

View file

@ -52,6 +52,9 @@ public class StoragePathPreference extends EditTextPreference {
f.setOpenDialogListener(new OpenFileDialog.OpenDialogListener() {
@Override
public void onFileSelected(String fileName) {
File f = new File(fileName);
if (!f.isDirectory())
fileName = f.getParent();
if (callChangeListener(fileName)) {
setText(fileName);
}
@ -68,4 +71,9 @@ public class StoragePathPreference extends EditTextPreference {
}
return s;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

View file

@ -4,10 +4,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".activities.RecordingActivity">
<com.github.axet.audiorecorder.widgets.EqualLinearLayout
@ -21,14 +17,18 @@
android:orientation="vertical">
<TextView
android:id="@+id/recording_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="2016-02-01.wav" />
android:padding="5dp"
android:text="2016-02-01.wav"
android:textSize="20dp" />
<TextView
android:id="@+id/recording_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="2016 02 01" />
</LinearLayout>
@ -39,13 +39,17 @@
android:orientation="vertical">
<TextView
android:id="@+id/recording_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="00:05" />
<TextView
android:id="@+id/recording_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="0.1 MB" />
</LinearLayout>
</com.github.axet.audiorecorder.widgets.EqualLinearLayout>
@ -54,24 +58,72 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.github.axet.audiorecorder.widgets.EqualLinearLayout
android:id="@+id/recording_detail"
<LinearLayout
android:id="@+id/recording_player"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="#dedede"
android:orientation="vertical"
android:padding="5dp">
<ImageView
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/play"
android:backgroundTint="@color/colorAccent" />
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
<TextView
android:id="@+id/recording_player_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="01:01" />
<SeekBar
android:id="@+id/recording_player_seek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="5dp"
android:progress="60" />
<TextView
android:id="@+id/recording_player_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="01:01" />
</LinearLayout>
<com.github.axet.audiorecorder.widgets.EqualLinearLayout
android:id="@+id/recording_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/trash"
android:backgroundTint="@color/colorAccent" />
</com.github.axet.audiorecorder.widgets.EqualLinearLayout>
android:orientation="horizontal">
<ImageView
android:id="@+id/recording_player_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/play"
android:backgroundTint="@color/colorAccent" />
<ImageView
android:id="@+id/recording_player_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/share"
android:backgroundTint="@color/colorAccent" />
<ImageView
android:id="@+id/recording_player_trash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/trash"
android:backgroundTint="@color/colorAccent" />
</com.github.axet.audiorecorder.widgets.EqualLinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 843 B

After

Width:  |  Height:  |  Size: 3.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 B

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After