Add touch feedback to GameGridActivity and AddDirectoryActivity.
This commit is contained in:
parent
24c6be9d0f
commit
3f1465196c
|
@ -4,6 +4,7 @@ import android.support.v7.widget.RecyclerView;
|
||||||
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.Toast;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.model.FileListItem;
|
import org.dolphinemu.dolphinemu.model.FileListItem;
|
||||||
|
@ -102,8 +103,14 @@ public class FileAdapter extends RecyclerView.Adapter<FileViewHolder> implements
|
||||||
return mFileList.size();
|
return mFileList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a file is clicked, determine if it is a directory; if it is, show that new directory's
|
||||||
|
* contents. If it is not, end the activity successfully.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view)
|
public void onClick(final View view)
|
||||||
{
|
{
|
||||||
String path = (String) view.getTag();
|
String path = (String) view.getTag();
|
||||||
|
|
||||||
|
@ -111,8 +118,26 @@ public class FileAdapter extends RecyclerView.Adapter<FileViewHolder> implements
|
||||||
|
|
||||||
if (clickedFile.isDirectory())
|
if (clickedFile.isDirectory())
|
||||||
{
|
{
|
||||||
mFileList = generateFileList(clickedFile);
|
final ArrayList<FileListItem> fileList = generateFileList(clickedFile);
|
||||||
notifyDataSetChanged();
|
|
||||||
|
if (fileList.isEmpty())
|
||||||
|
{
|
||||||
|
Toast.makeText(view.getContext(), R.string.add_directory_empty_folder, Toast.LENGTH_SHORT).show();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// Delay the loading of the new directory to give a little bit of time for UI feedback
|
||||||
|
// to happen. Hacky, but good enough for now; this is necessary because we're modifying
|
||||||
|
// the RecyclerView's contents, rather than constructing a new one.
|
||||||
|
view.getHandler().postDelayed(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
mFileList = fileList;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// Pass the activity the path of the parent directory of the clicked file.
|
// Pass the activity the path of the parent directory of the clicked file.
|
||||||
|
@ -120,6 +145,12 @@ public class FileAdapter extends RecyclerView.Adapter<FileViewHolder> implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given directory, return a list of Files it contains.
|
||||||
|
*
|
||||||
|
* @param directory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private ArrayList<FileListItem> generateFileList(File directory)
|
private ArrayList<FileListItem> generateFileList(File directory)
|
||||||
{
|
{
|
||||||
File[] children = directory.listFiles();
|
File[] children = directory.listFiles();
|
||||||
|
@ -145,6 +176,12 @@ public class FileAdapter extends RecyclerView.Adapter<FileViewHolder> implements
|
||||||
return mPath;
|
return mPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mostly just allows the activity's menu option to kick us up a level in the directory
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
*/
|
||||||
public void setPath(String path)
|
public void setPath(String path)
|
||||||
{
|
{
|
||||||
mPath = path;
|
mPath = path;
|
||||||
|
@ -154,8 +191,11 @@ public class FileAdapter extends RecyclerView.Adapter<FileViewHolder> implements
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface FileClickListener
|
/**
|
||||||
|
* Callback for when the user wants to add the visible directory to the library.
|
||||||
|
*/
|
||||||
|
public interface FileClickListener
|
||||||
{
|
{
|
||||||
public void finishSuccessfully();
|
void finishSuccessfully();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.dolphinemu.dolphinemu.adapters;
|
package org.dolphinemu.dolphinemu.adapters;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -9,12 +11,16 @@ import android.view.ViewGroup;
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog;
|
||||||
|
import org.dolphinemu.dolphinemu.emulation.EmulationActivity;
|
||||||
import org.dolphinemu.dolphinemu.model.Game;
|
import org.dolphinemu.dolphinemu.model.Game;
|
||||||
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
|
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class GameAdapter extends RecyclerView.Adapter<GameViewHolder>
|
public class GameAdapter extends RecyclerView.Adapter<GameViewHolder> implements
|
||||||
|
View.OnClickListener,
|
||||||
|
View.OnLongClickListener
|
||||||
{
|
{
|
||||||
private ArrayList<Game> mGameList;
|
private ArrayList<Game> mGameList;
|
||||||
|
|
||||||
|
@ -42,6 +48,9 @@ public class GameAdapter extends RecyclerView.Adapter<GameViewHolder>
|
||||||
View gameCard = LayoutInflater.from(parent.getContext())
|
View gameCard = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.card_game, parent, false);
|
.inflate(R.layout.card_game, parent, false);
|
||||||
|
|
||||||
|
gameCard.setOnClickListener(this);
|
||||||
|
gameCard.setOnLongClickListener(this);
|
||||||
|
|
||||||
// Use that view to create a ViewHolder.
|
// Use that view to create a ViewHolder.
|
||||||
GameViewHolder holder = new GameViewHolder(gameCard);
|
GameViewHolder holder = new GameViewHolder(gameCard);
|
||||||
return holder;
|
return holder;
|
||||||
|
@ -74,7 +83,6 @@ public class GameAdapter extends RecyclerView.Adapter<GameViewHolder>
|
||||||
{
|
{
|
||||||
holder.textDescription.setText(game.getDescription());
|
holder.textDescription.setText(game.getDescription());
|
||||||
}
|
}
|
||||||
holder.buttonDetails.setTag(game.getGameId());
|
|
||||||
|
|
||||||
holder.path = game.getPath();
|
holder.path = game.getPath();
|
||||||
holder.screenshotPath = game.getScreenPath();
|
holder.screenshotPath = game.getScreenPath();
|
||||||
|
@ -92,6 +100,45 @@ public class GameAdapter extends RecyclerView.Adapter<GameViewHolder>
|
||||||
return mGameList.size();
|
return mGameList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches the game that was clicked on.
|
||||||
|
*
|
||||||
|
* @param view The card representing the game the user wants to play.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onClick(View view)
|
||||||
|
{
|
||||||
|
GameViewHolder holder = (GameViewHolder) view.getTag();
|
||||||
|
|
||||||
|
// Start the emulation activity and send the path of the clicked ISO to it.
|
||||||
|
Intent intent = new Intent(view.getContext(), EmulationActivity.class);
|
||||||
|
|
||||||
|
intent.putExtra("SelectedGame", holder.path);
|
||||||
|
|
||||||
|
view.getContext().startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches the details activity for this Game, using an ID stored in the
|
||||||
|
* details button's Tag.
|
||||||
|
*
|
||||||
|
* @param view The Card button that was long-clicked.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view)
|
||||||
|
{
|
||||||
|
GameViewHolder holder = (GameViewHolder) view.getTag();
|
||||||
|
|
||||||
|
// Get the ID of the game we want to look at.
|
||||||
|
// TODO This should be all we need to pass in, eventually.
|
||||||
|
// String gameId = (String) holder.gameId;
|
||||||
|
|
||||||
|
Activity activity = (Activity) view.getContext();
|
||||||
|
GameDetailsDialog.newInstance(holder.game).show(activity.getFragmentManager(), "game_details");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static class SpacesItemDecoration extends RecyclerView.ItemDecoration
|
public static class SpacesItemDecoration extends RecyclerView.ItemDecoration
|
||||||
{
|
{
|
||||||
private int space;
|
private int space;
|
||||||
|
@ -108,7 +155,6 @@ public class GameAdapter extends RecyclerView.Adapter<GameViewHolder>
|
||||||
outRect.right = space;
|
outRect.right = space;
|
||||||
outRect.bottom = space;
|
outRect.bottom = space;
|
||||||
outRect.top = space;
|
outRect.top = space;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ public class GameViewHolder extends RecyclerView.ViewHolder
|
||||||
public ImageView imageScreenshot;
|
public ImageView imageScreenshot;
|
||||||
public TextView textGameTitle;
|
public TextView textGameTitle;
|
||||||
public TextView textDescription;
|
public TextView textDescription;
|
||||||
public ImageButton buttonDetails;
|
|
||||||
|
|
||||||
// Used to handle onClick(). Set this in onBindViewHolder().
|
// Used to handle onClick(). Set this in onBindViewHolder().
|
||||||
public String path;
|
public String path;
|
||||||
|
@ -30,54 +29,10 @@ public class GameViewHolder extends RecyclerView.ViewHolder
|
||||||
{
|
{
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
|
||||||
itemView.setOnClickListener(mCardClickListener);
|
itemView.setTag(this);
|
||||||
|
|
||||||
imageScreenshot = (ImageView) itemView.findViewById(R.id.image_game_screen);
|
imageScreenshot = (ImageView) itemView.findViewById(R.id.image_game_screen);
|
||||||
textGameTitle = (TextView) itemView.findViewById(R.id.text_game_title);
|
textGameTitle = (TextView) itemView.findViewById(R.id.text_game_title);
|
||||||
textDescription = (TextView) itemView.findViewById(R.id.text_game_description);
|
textDescription = (TextView) itemView.findViewById(R.id.text_game_description);
|
||||||
buttonDetails = (ImageButton) itemView.findViewById(R.id.button_details);
|
|
||||||
|
|
||||||
buttonDetails.setOnClickListener(mDetailsButtonListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private View.OnClickListener mCardClickListener = new View.OnClickListener()
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Launches the game that was clicked on.
|
|
||||||
*
|
|
||||||
* @param view The card representing the game the user wants to play.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onClick(View view)
|
|
||||||
{
|
|
||||||
// Start the emulation activity and send the path of the clicked ROM to it.
|
|
||||||
Intent intent = new Intent(view.getContext(), EmulationActivity.class);
|
|
||||||
|
|
||||||
intent.putExtra("SelectedGame", path);
|
|
||||||
|
|
||||||
view.getContext().startActivity(intent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private View.OnClickListener mDetailsButtonListener = new View.OnClickListener()
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launches the details activity for this Game, using an ID stored in the
|
|
||||||
* details button's Tag.
|
|
||||||
*
|
|
||||||
* @param view The Details button that was clicked on.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onClick(View view)
|
|
||||||
{
|
|
||||||
// Get the ID of the game we want to look at.
|
|
||||||
// TODO This should be all we need to pass in, eventually.
|
|
||||||
// String gameId = (String) view.getTag();
|
|
||||||
|
|
||||||
Activity activity = (Activity) view.getContext();
|
|
||||||
GameDetailsDialog.newInstance(game).show(activity.getFragmentManager(), "game_details");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,14 @@
|
||||||
|
|
||||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="200dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="250dp"
|
tools:layout_width="224dp"
|
||||||
android:transitionName="card_game">
|
android:layout_height="256dp"
|
||||||
|
android:transitionName="card_game"
|
||||||
|
android:focusable="true"
|
||||||
|
android:clickable="true"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -17,53 +22,37 @@
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:transitionName="image_game_screen"
|
android:transitionName="image_game_screen"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
tools:src="@drawable/placeholder_screenshot"/>
|
tools:src="@drawable/placeholder_screenshot"
|
||||||
|
tools:scaleType="centerCrop"/>
|
||||||
|
|
||||||
<RelativeLayout
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/text_game_title"
|
||||||
android:layout_height="72dp">
|
style="@android:style/TextAppearance.Material.Subhead"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_toStartOf="@+id/button_details"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:lines="1"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:text="The Legend of Zelda: The Wind Waker"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_game_description"
|
||||||
|
style="@android:style/TextAppearance.Material.Caption"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:lines="1"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:text="Zany rhythm action!"/>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_game_title"
|
|
||||||
style="@android:style/TextAppearance.Material.Subhead"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_below="@+id/image_game_screen"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_toStartOf="@+id/button_details"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:lines="1"
|
|
||||||
android:maxLines="1"
|
|
||||||
tools:text="Rhythm Heaven Fever"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_game_description"
|
|
||||||
style="@android:style/TextAppearance.Material.Caption"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignEnd="@+id/text_game_title"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignStart="@+id/text_game_title"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:layout_toStartOf="@+id/button_details"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:lines="1"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed odio vel quam auctor euismod. Pellentesque odio nibh, fermentum ut hendrerit id, ultrices et justo. "
|
|
||||||
tools:text="Zany rhythm action!"/>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/button_details"
|
|
||||||
style="@android:style/Widget.Material.Light.Button.Borderless.Small"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignTop="@+id/text_game_title"
|
|
||||||
android:src="@drawable/ic_action_overflow"/>
|
|
||||||
</RelativeLayout>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</android.support.v7.widget.CardView>
|
</android.support.v7.widget.CardView>
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="56dp">
|
android:layout_height="56dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image_type"
|
android:id="@+id/image_type"
|
||||||
android:background="@drawable/oval_ripple_grey"
|
|
||||||
tools:src="@drawable/ic_wii"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:padding="4dp"/>
|
android:background="@drawable/oval_ripple_grey"
|
||||||
|
android:padding="4dp"
|
||||||
|
tools:src="@drawable/ic_wii"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/text_file_name"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
tools:text="File Name"
|
android:layout_weight="1"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:layout_gravity="center_vertical"
|
tools:text="File Name"/>
|
||||||
android:id="@+id/text_file_name"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- TODO Please give me an icon! -->
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_up_one_level"
|
android:id="@+id/menu_up_one_level"
|
||||||
android:title="@string/add_directory_up_one_level"
|
android:title="@string/add_directory_up_one_level"
|
||||||
|
|
|
@ -221,6 +221,7 @@
|
||||||
<string name="other">Other</string>
|
<string name="other">Other</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="add_directory_title">Add Directory to Library</string>
|
<string name="add_directory_title">Add Folder to Library</string>
|
||||||
<string name="add_directory_up_one_level">Up one level</string>
|
<string name="add_directory_up_one_level">Up one level</string>
|
||||||
|
<string name="add_directory_empty_folder">That folder is empty.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue