Added TabAdpater and Fragments for Installing and Config Editing
This commit is contained in:
parent
361eef5b9a
commit
f52408abff
|
@ -1,48 +0,0 @@
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
import com.MartyrPher.smapiandroidinstaller.ApkExtractor;
|
|
||||||
import com.MartyrPher.smapiandroidinstaller.BackgroundTask;
|
|
||||||
import com.MartyrPher.smapiandroidinstaller.DialogFrag;
|
|
||||||
import com.MartyrPher.smapiandroidinstaller.MainActivity;
|
|
||||||
import com.MartyrPher.smapiandroidinstaller.R;
|
|
||||||
|
|
||||||
//import androidx.annotation.NonNull;
|
|
||||||
//import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
public class InstallFragment extends Fragment {
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
|
||||||
// {
|
|
||||||
// final Button start_button = view.findViewById(R.id.start_button);
|
|
||||||
// start_button.setOnClickListener(new View.OnClickListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onClick(View v) {
|
|
||||||
// start_button.setBackgroundColor(getResources().getColor(R.color.colorAccent));
|
|
||||||
// if (true)
|
|
||||||
// {
|
|
||||||
// boolean[] foundGame;
|
|
||||||
// ApkExtractor apkExtractor = new ApkExtractor(null);
|
|
||||||
//
|
|
||||||
// foundGame = apkExtractor.checkForInstallOrUpgrade();
|
|
||||||
//
|
|
||||||
// if((foundGame[0] || foundGame[1]))
|
|
||||||
// {
|
|
||||||
// BackgroundTask backgroundTask = new BackgroundTask(null, apkExtractor, foundGame[0]);
|
|
||||||
// backgroundTask.execute();
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// DialogFrag.showDialog(null, R.string.cant_find, 1);
|
|
||||||
// start_button.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config Adapter used to show the different configs and their views
|
||||||
|
*/
|
||||||
|
public class ConfigAdapter extends RecyclerView.Adapter<ConfigAdapter.ConfigViewHolder>
|
||||||
|
{
|
||||||
|
//TAG used for debugging purposes
|
||||||
|
private final static String TAG = "ConfigAdapter";
|
||||||
|
|
||||||
|
//List of the mods
|
||||||
|
private List<File> mModFiles;
|
||||||
|
|
||||||
|
//ViewHolder class that extends RecyclerView.ViewHolder
|
||||||
|
public static class ConfigViewHolder extends RecyclerView.ViewHolder
|
||||||
|
{
|
||||||
|
//The view that needs to be inflated
|
||||||
|
public View mConstraintLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that sets the layout
|
||||||
|
* @param layout = The views layout
|
||||||
|
*/
|
||||||
|
public ConfigViewHolder(View layout)
|
||||||
|
{
|
||||||
|
super(layout);
|
||||||
|
mConstraintLayout = layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that sets the Mod File list
|
||||||
|
* @param modFiles = The list of Mod Files
|
||||||
|
*/
|
||||||
|
public ConfigAdapter(List<File> modFiles)
|
||||||
|
{
|
||||||
|
mModFiles = modFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets called when a view pops into the RecyclerView
|
||||||
|
* @param parent = The parent viewgroup
|
||||||
|
* @param viewType = The view type
|
||||||
|
* @return The configViewHolder
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ConfigAdapter.ConfigViewHolder onCreateViewHolder(final ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
//Inflate the view
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.text_view, parent, false);
|
||||||
|
|
||||||
|
//Create a new ConfigViewHolder
|
||||||
|
final ConfigViewHolder configViewHolder = new ConfigViewHolder(view);
|
||||||
|
|
||||||
|
//Set an onClickListner for each of the config options
|
||||||
|
view.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v){
|
||||||
|
//The position in the RecyclerView
|
||||||
|
final int position = ConfigEditorFragment.mRecyclerView.getChildLayoutPosition(v);
|
||||||
|
|
||||||
|
//Save button
|
||||||
|
final Button saveButton = configViewHolder.mConstraintLayout.findViewById(R.id.save_button);
|
||||||
|
|
||||||
|
//Cancel Button
|
||||||
|
final Button cancelButton = configViewHolder.mConstraintLayout.findViewById(R.id.cancel_button);
|
||||||
|
|
||||||
|
//Edit Text
|
||||||
|
final EditText editText = configViewHolder.mConstraintLayout.findViewById(R.id.editText);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//When clicked read the json and make the buttons VISIBLE
|
||||||
|
editText.setText(readStringFromJson(position));
|
||||||
|
editText.setVisibility(View.VISIBLE);
|
||||||
|
saveButton.setVisibility(View.VISIBLE);
|
||||||
|
saveButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Try to save the json when the save button is clicked
|
||||||
|
writeStringToJson(editText.getText().toString(), position);
|
||||||
|
|
||||||
|
//Set the edit text to an empty string and set everything to INVISIBLE
|
||||||
|
editText.setText("");
|
||||||
|
editText.setVisibility(View.INVISIBLE);
|
||||||
|
saveButton.setVisibility(View.INVISIBLE);
|
||||||
|
cancelButton.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
catch(IOException io)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
//When cancel is clicked, set everything to INVISIBLE again
|
||||||
|
cancelButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
editText.setText("");
|
||||||
|
editText.setVisibility(View.INVISIBLE);
|
||||||
|
saveButton.setVisibility(View.INVISIBLE);
|
||||||
|
cancelButton.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (IOException io)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return configViewHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that shows the initial mod name when the View is binded to the RecyclerView
|
||||||
|
* @param holder = The ConfigViewHolder
|
||||||
|
* @param position = The position of the item in the RecyclerView
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(ConfigViewHolder holder, int position)
|
||||||
|
{
|
||||||
|
//Grab the textView and set the string to the mods name
|
||||||
|
TextView textView = holder.mConstraintLayout.findViewById(R.id.textView3);
|
||||||
|
textView.setText(mModFiles.get(position).getParentFile().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets called when a view is recycled from the RecyclerView
|
||||||
|
* This is needed or a UI bug shows up when opening a config file (Thanks BluPenDragon!)
|
||||||
|
* @param holder = The ConfigViewHolder
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onViewRecycled(ConfigViewHolder holder)
|
||||||
|
{
|
||||||
|
//Get the save button, cancel button and edit text from the holder
|
||||||
|
Button saveButton = holder.mConstraintLayout.findViewById(R.id.save_button);
|
||||||
|
Button cancelButton = holder.mConstraintLayout.findViewById(R.id.cancel_button);
|
||||||
|
EditText text = holder.mConstraintLayout.findViewById(R.id.editText);
|
||||||
|
|
||||||
|
//Make them all INVISIBLE and set the edit text to an empty string
|
||||||
|
saveButton.setVisibility(View.INVISIBLE);
|
||||||
|
cancelButton.setVisibility(View.INVISIBLE);
|
||||||
|
text.setText("");
|
||||||
|
text.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets the amount of items in the Mod File list
|
||||||
|
* @return The size of the Mod File list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getItemCount()
|
||||||
|
{
|
||||||
|
return mModFiles.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to write the string in the edit text to json
|
||||||
|
* @param text = The text that tries to be saved
|
||||||
|
* @param position = The position of the item that is being saved
|
||||||
|
* @throws IOException if the output fails
|
||||||
|
*/
|
||||||
|
private void writeStringToJson(String text, int position) throws IOException
|
||||||
|
{
|
||||||
|
//BufferedWriter to write the string to the json file
|
||||||
|
BufferedWriter outConfig = new BufferedWriter(new FileWriter(mModFiles.get(position).getAbsolutePath()));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//write the text
|
||||||
|
outConfig.write(text);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//close the file
|
||||||
|
outConfig.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the json file from the mod folder into a string for editing
|
||||||
|
* @param position = The position of the string to edit
|
||||||
|
* @return The json content in String form
|
||||||
|
* @throws IOException if the read fails
|
||||||
|
*/
|
||||||
|
//Reads the json file from the mod folder into a string for editing
|
||||||
|
private String readStringFromJson(int position) throws IOException
|
||||||
|
{
|
||||||
|
//Use a Scanner with a delimiter to parse into string
|
||||||
|
String content = new Scanner(new File(mModFiles.get(position).getAbsolutePath())).useDelimiter("\\Z").next();
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment used to handle config editing
|
||||||
|
*/
|
||||||
|
public class ConfigEditorFragment extends Fragment {
|
||||||
|
|
||||||
|
//Tag used for debug purposes
|
||||||
|
private final static String TAG = "ConfigEditorFragment";
|
||||||
|
|
||||||
|
//Constant string used the mod directory
|
||||||
|
private final static String MOD_DIR = Environment.getExternalStorageDirectory() + "/StardewValley/Mods/";
|
||||||
|
|
||||||
|
//The Recycler View
|
||||||
|
public static RecyclerView mRecyclerView;
|
||||||
|
|
||||||
|
//The Recycler Views adapter
|
||||||
|
private RecyclerView.Adapter mAdapter;
|
||||||
|
|
||||||
|
//The Recycler Views layout manager
|
||||||
|
private RecyclerView.LayoutManager mLayoutManager;
|
||||||
|
|
||||||
|
//The list of mod files
|
||||||
|
private final static List<File> mModFiles = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets called when the view needs to be created
|
||||||
|
* @param inflater = The layout inflator
|
||||||
|
* @param container = The container to inflate the view
|
||||||
|
* @param savedInstanceState = The savedInstanceState
|
||||||
|
* @return the inflated view/layout
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
//Inflate the fragment layout
|
||||||
|
return inflater.inflate(R.layout.config_editing, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets called when the view is created, used to setup the Recycler View
|
||||||
|
* @param view = The view that was created
|
||||||
|
* @param savedInstanceState = The savedInstanceState
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
//Find the Recycler View and set the hasFixedSize
|
||||||
|
mRecyclerView = view.findViewById(R.id.recycler_view);
|
||||||
|
mRecyclerView.setHasFixedSize(false);
|
||||||
|
|
||||||
|
//Create a new Layout Manager and set Recyclers View layout manager
|
||||||
|
mLayoutManager = new LinearLayoutManager(getActivity());
|
||||||
|
mRecyclerView.setLayoutManager(mLayoutManager);
|
||||||
|
|
||||||
|
//Only grab the mod file list once
|
||||||
|
//Not having this allows duplicate mods to show (Thanks Minerva!!!)
|
||||||
|
if (!MainActivity.mHasFoundMods)
|
||||||
|
getModFiles();
|
||||||
|
|
||||||
|
//Create a new Config Adapter and set Recycle Views adapter to the new adapter
|
||||||
|
mAdapter = new ConfigAdapter(mModFiles);
|
||||||
|
mRecyclerView.setAdapter(mAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mod files using a recursive file check
|
||||||
|
*/
|
||||||
|
private void getModFiles()
|
||||||
|
{
|
||||||
|
File modFolder = new File(MOD_DIR);
|
||||||
|
for (File file : modFolder.listFiles())
|
||||||
|
{
|
||||||
|
recursiveFileCheck(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set that the mods were found and sort the list
|
||||||
|
MainActivity.mHasFoundMods = true;
|
||||||
|
Collections.sort(mModFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive file check that searches for config files within the mod folder
|
||||||
|
* @param file = The file that is being checked
|
||||||
|
*/
|
||||||
|
private void recursiveFileCheck(File file)
|
||||||
|
{
|
||||||
|
if (file.isDirectory())
|
||||||
|
{
|
||||||
|
for (File configFile : file.listFiles()) {
|
||||||
|
recursiveFileCheck(configFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//If it's a config then add it to the list!
|
||||||
|
if (file.getName().equals("config.json"))
|
||||||
|
mModFiles.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment that shows the Install Button
|
||||||
|
*/
|
||||||
|
public class InstallFragment extends Fragment {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets called when the view needs to be created
|
||||||
|
* @param inflater = The layout inflator
|
||||||
|
* @param container = The container to inflate the view in
|
||||||
|
* @param savedInstanceState = The savedInstanceState
|
||||||
|
* @return the inflated view
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
//Inflate the fragment layout
|
||||||
|
return inflater.inflate(R.layout.activity_main, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets called when the view is created, used to setup the Recycler View
|
||||||
|
* @param view = The view that was created
|
||||||
|
* @param savedInstanceState = The savedInstanceState
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
//Start button, one click install. Can't beat it.
|
||||||
|
final Button start_button = view.findViewById(R.id.start_button);
|
||||||
|
start_button.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
start_button.setBackgroundColor(getResources().getColor(R.color.colorAccent));
|
||||||
|
|
||||||
|
//Did the user give permission to storage
|
||||||
|
if (MainActivity.mHasPermissions)
|
||||||
|
{
|
||||||
|
boolean[] foundGame;
|
||||||
|
ApkExtractor apkExtractor = new ApkExtractor(getActivity());
|
||||||
|
|
||||||
|
//Did it find the game.
|
||||||
|
foundGame = apkExtractor.checkForInstallOrUpgrade();
|
||||||
|
|
||||||
|
if((foundGame[0] || foundGame[1]))
|
||||||
|
{
|
||||||
|
//Start the task
|
||||||
|
BackgroundTask backgroundTask = new BackgroundTask(getActivity(), apkExtractor, foundGame[0]);
|
||||||
|
backgroundTask.execute();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Show the dialog saying that the game can't be found
|
||||||
|
DialogFrag.showDialog(getActivity(), R.string.cant_find, 1);
|
||||||
|
start_button.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the tabs at the top of the screen
|
||||||
|
*/
|
||||||
|
public class TabAdapter extends FragmentStatePagerAdapter {
|
||||||
|
|
||||||
|
//List of the fragments
|
||||||
|
private final static List<Fragment> mFragmentList = new ArrayList<>();
|
||||||
|
|
||||||
|
//List of the fragment titles
|
||||||
|
private final static List<String> mTitleList = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that sets the fragment manager
|
||||||
|
* @param fragmentManager = The fragment manager
|
||||||
|
*/
|
||||||
|
public TabAdapter(FragmentManager fragmentManager)
|
||||||
|
{
|
||||||
|
super(fragmentManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override that gets the item at a specific position
|
||||||
|
* @param position = The position of the item
|
||||||
|
* @return the position in the fragment list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position)
|
||||||
|
{
|
||||||
|
return mFragmentList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a fragment to the list and add the title
|
||||||
|
* @param fragment = The fragment to add
|
||||||
|
* @param title = The title to add
|
||||||
|
*/
|
||||||
|
public void addFragment(Fragment fragment, String title)
|
||||||
|
{
|
||||||
|
mFragmentList.add(fragment);
|
||||||
|
mTitleList.add(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the page title
|
||||||
|
* @param position = The position to get
|
||||||
|
* @return the position of the title in the list
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public CharSequence getPageTitle(int position)
|
||||||
|
{
|
||||||
|
return mTitleList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of fragments in the list
|
||||||
|
* @return the size of the fragment list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getCount()
|
||||||
|
{
|
||||||
|
return mFragmentList.size();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue