Added TabAdpater and Fragments for Installing and Config Editing

This commit is contained in:
Chris 2019-11-12 18:46:38 -05:00
parent 361eef5b9a
commit f52408abff
5 changed files with 480 additions and 48 deletions

View File

@ -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));
// }
//
// }
// }
// });
//
// }
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View 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));
}
}
}
});
}
}

View File

@ -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();
}
}