How to show file contents in recyclerview? - android

Hello I am creating an app which reads a file and its contents should be shown in recyclerview, I have done it but only first line is showing remaining lines are not showing
My file contains data as shown below
123
345
567
I have used buffered reader and input stream to read file
Here is the class for recyclerAdapter
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.Phone> {
List<PhoneNumber> phoneNumbers;
public RecyclerAdapter(List<PhoneNumber> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
#NonNull
#Override
public Phone onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.text,viewGroup,false);
Phone phone = new Phone(view);
return phone;
}
#Override
public void onBindViewHolder(#NonNull Phone phone, int i) {
phone.textView.setText(phoneNumbers.get(i).number);
}
#Override
public int getItemCount() {
return phoneNumbers.size();
}
public class Phone extends RecyclerView.ViewHolder {
TextView textView;
public Phone(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.txt);
}
}
}
Here is the code of my class
public class ScheduledFragment extends Fragment {
String[] strings;
RecyclerView listView;
List<PhoneNumber> phoneNumbers;
public ScheduledFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_scheduled, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listView = view.findViewById(R.id.list);
ReadFile();
initialiseAdapter();
}
private void initialiseAdapter() {
listView.setHasFixedSize(true);
listView.setLayoutManager(new LinearLayoutManager(getContext()));
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(phoneNumbers);
listView.setAdapter(recyclerAdapter);
}
private void ReadFile() {
phoneNumbers = new ArrayList<>();
try {
InputStream inputStream = getActivity().getAssets().open("phone.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
boolean hasNext = true;
while (hasNext) {
String line = bufferedReader.readLine();
phoneNumbers.add(new PhoneNumber(line));
hasNext = line != null;
}
inputStream.close();
} catch (IOException e) {
//log the exception
}
}
}
class PhoneNumber {
String number;
public PhoneNumber() {
}
public PhoneNumber(String number) {
this.number = number;
}
}
I am only getting first line show in recyclerview
Expected results:
123
345
567
results I am getting:
123

Try to improve your while, you don't need a variable for this:
while (true) {
String line = bufferedReader.readLine();
if(line == null) {
break;
} else if (line.equals("")) {
phoneNumbers.add(new PhoneNumber("\n"));
/*I'm not sure if you really want "/n" breaks*/
} else {
phoneNumbers.add(new PhoneNumber(line));
}
Log.d("test", line);
}
ps: for convention use capital letters only for Classes not methods (readFile not ReadFile)

Related

Fetched data from mvvm is not updated in recycler view on first visit

PreAdmissionList.java
public class PreAdmissionList extends Fragment implements View.OnClickListener, AdapterApprovalList.OnItemClickListener {
private BasicInfoViewModel basicInfoViewModel;
private AdapterApprovalList adapterApprovalList;
private RecyclerView rvApprovalList;
public PreAdmissionList() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_pre_admission_list, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.fab_add_new_admission).setOnClickListener(this);
rvApprovalList = view.findViewById(R.id.rv_approval_list);
basicInfoViewModel = new ViewModelProvider(requireActivity()).get(BasicInfoViewModel.class);
basicInfoViewModel.init();
basicInfoViewModel.getApprovalList().observe(getViewLifecycleOwner(), new Observer<List<ModelBasicInfo>>() {
#Override
public void onChanged(List<ModelBasicInfo> modelBasicInfos) {
adapterApprovalList.notifyDataSetChanged();
}
});
initRecyclerView();
}
private void initRecyclerView() {
adapterApprovalList = new AdapterApprovalList(this,basicInfoViewModel.getApprovalList().getValue());
rvApprovalList.setHasFixedSize(true);
rvApprovalList.setLayoutManager(new LinearLayoutManager(getContext()));
rvApprovalList.setAdapter(adapterApprovalList);
}
}
AdapterApprovalList.java
public class AdapterApprovalList extends RecyclerView.Adapter<AdapterApprovalList.ALViewHolder>{
private Context context;
private OnItemClickListener onItemClickListener;
private List<ModelBasicInfo> modelBasicInfoList;
public AdapterApprovalList(OnItemClickListener onItemClickListener,List<ModelBasicInfo> modelBasicInfoList) {
this.onItemClickListener = onItemClickListener;
this.modelBasicInfoList=modelBasicInfoList;
}
#NonNull
#Override
public ALViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
View view = LayoutInflater.from(context).inflate(R.layout.template_approval_list_item,parent,false);
return new ALViewHolder(view,onItemClickListener);
}
#Override
public void onBindViewHolder(#NonNull ALViewHolder holder, int position) {
ModelBasicInfo basicInfo = modelBasicInfoList.get(position);
StringBuilder fullName = new StringBuilder();
fullName.append(basicInfo.getFirstName()).append(" ");
fullName.append(basicInfo.getMiddleName()).append(" ");
fullName.append(basicInfo.getLastName()).append(" ");
holder.fullName.setText(fullName);
holder.id.setText("RKC00"+String.valueOf(basicInfo.getId()));
}
#Override
public int getItemCount() {
return modelBasicInfoList.size();
}
static class ALViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
OnItemClickListener mOnItemClickListener;
TextView fullName,id;
public ALViewHolder(#NonNull View itemView,OnItemClickListener mOnItemClickListener) {
super(itemView);
this.mOnItemClickListener = mOnItemClickListener;
fullName = itemView.findViewById(R.id.tv_text_full_name);
id = itemView.findViewById(R.id.tv_text_approval_id);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
mOnItemClickListener.onApprovalItemClick(getAbsoluteAdapterPosition());
}
}
public interface OnItemClickListener{
void onApprovalItemClick(int position);
}
}
BasicInfoViewModel.java
public class BasicInfoViewModel extends ViewModel {
private BasicInfoRepo basicInfoRepo;
private MutableLiveData<List<ModelBasicInfo>> approvalList;
public void init(){
if(approvalList != null){
return;
}
basicInfoRepo = BasicInfoRepo.getInstance();
approvalList = basicInfoRepo.getApprovalList();
}
public LiveData<List<ModelBasicInfo>> getApprovalList(){
return approvalList;
}
public void insertBasicInfo(ModelBasicInfo modelBasicInfo){
basicInfoRepo.insertData(modelBasicInfo);
}
public void updateApprovalStatus(int id){
basicInfoRepo.updateStatus(id);
}
}
BasicInfoRepo.java
public class BasicInfoRepo {
private static BasicInfoRepo instance;
static ConnectionClass connectionClass = new ConnectionClass();
private List<ModelBasicInfo> approvalList = new ArrayList<>();
public static BasicInfoRepo getInstance(){
if(instance== null){
instance = new BasicInfoRepo();
}
return instance;
}
public MutableLiveData<List<ModelBasicInfo>> getApprovalList(){
loadApprovalList();
MutableLiveData<List<ModelBasicInfo>> mList = new MutableLiveData<>();
mList.setValue(approvalList);
return mList;
}
private void loadApprovalList() {
LoadApprovalList loadApprovalList = new LoadApprovalList();
loadApprovalList.execute();
}
public void insertData(ModelBasicInfo modelBasicInfo){
InsertBasicInfo insertBasicInfo = new InsertBasicInfo();
insertBasicInfo.execute(modelBasicInfo);
}
public void updateStatus(int id){
UpdateBasicInfo updateBasicInfo = new UpdateBasicInfo();
updateBasicInfo.execute(id);
}
private static class InsertBasicInfo extends AsyncTask<ModelBasicInfo,Integer,String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(ModelBasicInfo... model) {
String result = null;
// Log.i("Testing db",lists[0].get(0).getFirstName());
try{
Connection connection = connectionClass.CONN();
if(connection==null){
result = "Error in connection !!!";
}else{
//Date object
Date date= new Date();
//getTime() returns current time in milliseconds
long time = date.getTime();
//Passed the milliseconds to constructor of Timestamp class
Timestamp ts = new Timestamp(time);
PreparedStatement ps = connection.prepareStatement("insert into PreAdmissionDetails values(?,?,?,?,?,?,?,?,?,?)");
ps.setString(1,model[0].getFirstName());
ps.setString(2,model[0].getMiddleName());
ps.setString(3,model[0].getLastName());
ps.setString(4,model[0].getMotherName());
ps.setDate(5, java.sql.Date.valueOf(model[0].getDateOfBirth()));
ps.setString(6,model[0].getMobileNo());
ps.setInt(7,0);
ps.setInt(8,0);
ps.setBoolean(9,false);
ps.setTimestamp(10, ts);
ps.executeUpdate();
result = "Submitted Successfully !!!";
}
}catch (Exception ex){
Log.e("sqlerror",ex.toString());
result=ex.getMessage();
}
Log.e("sqlerror","result : "+result);
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
private static class UpdateBasicInfo extends AsyncTask<Integer,Integer,String>{
#Override
protected String doInBackground(Integer... integers) {
String result = null;
try{
Connection connection = connectionClass.CONN();
if(connection==null){
result = "Error in connection !!!";
}else{
PreparedStatement ps = connection.prepareStatement("UPDATE PreAdmissionDetails SET STATUS=? WHERE id=?");
ps.setInt(1,0);
ps.setInt(2,integers[0]);
ps.executeUpdate();
result = "Updated Successfully !!!";
}
}catch (Exception ex){
Log.e("sqlerror",ex.toString());
result=ex.getMessage();
}
Log.e("sqlerror","result : "+result.toString());
return result;
}
}
private class LoadApprovalList extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
String result = null;
try{
Connection connection = connectionClass.CONN();
if(connection==null){
result = "Error in connection !!!";
}else{
PreparedStatement ps = connection.prepareStatement("select * from preadmissiondetails");
ResultSet rs = ps.executeQuery();
approvalList.clear();
while (rs.next()) {
approvalList.add(new ModelBasicInfo(rs.getInt(1),
rs.getString(2),
rs.getString(3),
rs.getString(4),
rs.getString(5),
rs.getString(6),
rs.getString(7),
rs.getInt(8),
rs.getInt(9),
rs.getBoolean(10)));}
result = "Fetched Successfully !!!";
}
}catch (Exception ex){
Log.e("sqlerror",ex.toString());
result=ex.getMessage();
}
Log.e("sqlerror","result : "+result.toString());
return null;
}
}
}
Problem is here that when I open the app no items in the recycler view, Firsty I thought may be slow internet it will fetch data in after some time but it doesn't show data. But when I navigate to some other fragments and return to the preadmission list it shows data.
Your problem is here:
public MutableLiveData<List<ModelBasicInfo>> getApprovalList(){
loadApprovalList();
MutableLiveData<List<ModelBasicInfo>> mList = new MutableLiveData<>();
mList.setValue(approvalList);
return mList;
}
loadApprovalList() launches an AsyncTask, which is an asynchronous operation (in other words, it takes time to produce a result). The getApprovalList() method doesn't just halt right there and wait for loadApprovalList() to complete. It continues right along and returns an empty list the first time it executes. But by the second time it executes, approvalList now has a value because the AsyncTask has completed. So it returns the correct data that second time it executes. It executes a second time when you return to your Fragment because the init block in your ViewModel is executing a second time at that point.
The solution is to make approvalList a LiveData. That way, when the AsyncTask updates approvalList, your ViewModel can observe the change. Your ViewModel should observe approvalList in your Repository, just like how your Fragment is observing the getApprovalList() method in your ViewModel.

Passing Data from Recycler View to new Activity in a Quote Application,new activity is opening but data not coming

I'm creating a Quote Application where quote will be inside recycler view ,and on click same quote
will appear on which user clicked.As I tried using on Click Listener inside View Holder in Adapter
Class,app activity changed to other,but data not showing.
My Adapter Class.
public class QuotesAdapter extends RecyclerView.Adapter<QuotesAdapter.QuotesViewHolder> {
List<String> quotes = null;
Context context;
public QuotesAdapter(List<String> quotes, Context context) {
this.quotes = quotes;
this.context = context;
}
#NonNull
#Override
public QuotesViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_item_quote, viewGroup, false);
return new QuotesViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final QuotesViewHolder quotesViewHolder, int i) {
String[] colors = {"#448AFF", "#FFC107", "#009688", "#E91E63", "#FF5722"};
final String quote = quotes.get(i);
quotesViewHolder.txtQuote.setText(quote);
int color = i % colors.length;
final int intColor = Color.parseColor(colors[color]);
quotesViewHolder.quoteContainer.setBackgroundColor(intColor);
}
#Override
public int getItemCount() {
return quotes.size();
}
public class QuotesViewHolder extends RecyclerView.ViewHolder {
TextView txtQuote;
LinearLayout quoteContainer;
public QuotesViewHolder(#NonNull View itemView) {
super(itemView);
txtQuote = itemView.findViewById(R.id.txtQuote);
quoteContainer = itemView.findViewById(R.id.quoteContainer);
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView quoteList = findViewById(R.id.quoteList);
quoteList.setLayoutManager(new LinearLayoutManager(this ));
quoteList.setAdapter(new QuotesAdapter(getQuotes(), this));
}
private List<String> getQuotes(){
List<String> quotes = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(this.getAssets().open("quotes.txt"), "UTF-8"));
String line;
while ((line = bufferedReader.readLine()) != null){
quotes.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
if(bufferedReader != null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return quotes;
}
}
On your itemClick in adapter use bundle to pass data
Intent intent = new Intent(context, NewActivity.class);
intent.putExtra("myKey", AnyValue);
startActivity(intent);
You can get the passed values by this way:
Bundle extras = intent.getExtras();
String myString = extras.getString("myKey");

How to access a list in a hosting Activity from an external AlertDialog

I have a recyclerView with a list of Competitor objects. The list that populates the RecyclerView is a global Singleton. In that Singleton's constructor I open a Json file, parse it's contents to populate the global Singleton's list of Competitors and use that list to pass to the RecyclerView's adapter. Each list item has an ImageButton. This is what I'm trying to accomplish;
When the user clicks on the ImageButton (Delete Button) I want an AlertDialog to pop up and ask the user if they are sure they want to delete the Competitor. This part I have so far. But what I need to do next I can't figure out. I am able to update the json file that contains the global list's information but I also want to update the recyclerview by removing the Competitor from the RecyclerView by calling:
mCompetitorsList.remove(competitor); notifyItemRemoved(position);
However I can't get a reference to the mCompetitorsList variable from an external Dialog class. The same goes for calling notifiyItemRemoved(position)
What should I do? Below is the code for my Dialog class, my Activity that contains the RecyclerView and it's Adapter as well as the Singleton implementation.
public class MasterCompetitorsListActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
private static final String DIALOG_DELETE_COMPETITOR = "DIALOG_DELETE_COMPETITOR";
private RecyclerView mRecyclerView;
private List<Competitor> mCompetitorsList;
private CompetitorListAdapter mAdapter;
private SearchView mSearchView;
private FloatingActionButton mAddCompetitorButton;
private Button mDeletCompetitor;
private TextView mCompetitorHidden;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master_competitors_list);
mSearchView = (SearchView) findViewById(R.id.searchView);
mSearchView.setOnQueryTextListener(this);
/* initialize the Global Competitor's List for the recyclerview. Because this is a singleton
it should initialize the list for the entire app's runtime
*/
GlobalCompetitorsList.get();
mCompetitorsList = GlobalCompetitorsList.getCompetitors();
mRecyclerView = (RecyclerView) findViewById(R.id.master_competitors_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
mAdapter = new CompetitorListAdapter(this, mCompetitorsList);
mRecyclerView.setAdapter(mAdapter);
// set a separator for the list items
DividerItemDecoration divider = new DividerItemDecoration(
mRecyclerView.getContext(),
layoutManager.getOrientation());
divider.setDrawable(ContextCompat.getDrawable(MasterCompetitorsListActivity.this, R.drawable.divider_dark));
mRecyclerView.addItemDecoration(divider);
mRecyclerView.setAdapter(mAdapter);
mAddCompetitorButton = (FloatingActionButton) findViewById(R.id.add_master_competitor_floating_button);
mAddCompetitorButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MasterCompetitorsListActivity.this, AddNewMasterCompetitorActivity.class);
startActivity(intent);
}
});
}
#Override
public boolean onQueryTextSubmit(String query) {
mCompetitorsList = new ArrayList<>();
mCompetitorsList = GlobalCompetitorsList.getCompetitors();
mAdapter.notifyDataSetChanged();
return false;
}
#Override
public boolean onQueryTextChange(String query) {
mCompetitorsList = GlobalCompetitorsList.getCompetitors();
query = query.toLowerCase();
final List<Competitor> filteredList = new ArrayList<>();
for (int i = 0; i < mCompetitorsList.size(); i++) {
final String lastName = mCompetitorsList.get(i).getLastName().toLowerCase();
final String firstName = mCompetitorsList.get(i).getFirstName().toLowerCase();
if (lastName.contains(query) || firstName.contains(query)) {
filteredList.add(mCompetitorsList.get(i));
}
}
mAdapter.setFilter(filteredList);
return true;
}
// ********* RecyclerView Adapter class *************************************************************************
public class CompetitorListAdapter extends RecyclerView.Adapter<CompetitorListAdapter.CompetitorViewHolder> {
List<Competitor> mCompetitors;
Context mContext;
public CompetitorListAdapter(Context context, List<Competitor> competitors) {
mContext = context;
mCompetitors = competitors;
}
#Override
public CompetitorListAdapter.CompetitorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(MasterCompetitorsListActivity.this);
View itemView = inflater.inflate(R.layout.list_item_master_competitor, parent, false);
CompetitorViewHolder viewHolder = new CompetitorViewHolder(itemView);
return viewHolder;
}
#Override
public void onBindViewHolder(CompetitorListAdapter.CompetitorViewHolder holder, final int position) {
final Competitor competitor = mCompetitorsList.get(position);
try {
holder.firstName.setText(competitor.getFirstName());
holder.lastName.setText(competitor.getLastName());
holder.memberNum.setText(competitor.getMemberNum());
holder.deleteCompetitor.setImageResource(R.drawable.ic_delete_forever_white_24dp);
holder.container.findViewById(R.id.main_container);
holder.hiddenCompetitorId.setText(competitor.getCompetitorId().toString());
} catch (Exception e) {
e.printStackTrace();
}
holder.deleteCompetitor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = getSupportFragmentManager();
DeleteCompetitorDialogFragment dialog = new DeleteCompetitorDialogFragment();
dialog.show(fragmentManager, DIALOG_DELETE_COMPETITOR);
// mCompetitorsList.remove(competitor); // remove from the global singleton list
// notifyItemRemoved(position);
}
});
}
#Override
public int getItemCount() {
return mCompetitorsList.size();
}
// ************* View Holder Class **************************************************************************
public class CompetitorViewHolder extends RecyclerView.ViewHolder {
public TextView firstName;
public TextView lastName;
public TextView memberNum;
public ImageButton deleteCompetitor;
public ConstraintLayout container;
public TextView hiddenCompetitorId;
boolean comptitorIsActive = false;
public CompetitorViewHolder(final View itemView) {
super(itemView);
firstName = (TextView) itemView.findViewById(R.id.first_name);
lastName = (TextView) itemView.findViewById(R.id.last_name);
deleteCompetitor = (ImageButton) itemView.findViewById(R.id.delete_competitor_button);
hiddenCompetitorId = (TextView) itemView.findViewById(R.id.competitor_id_hidden);
container = (ConstraintLayout) itemView.findViewById(R.id.main_container);
memberNum = (TextView) itemView.findViewById(R.id.member_num);
}
}
// ************ End of View Holder Class ********************************************************************
public void setFilter(List<Competitor> newList) {
mCompetitorsList = new ArrayList<>();
mCompetitorsList.addAll(newList);
notifyDataSetChanged();
}
}
// ************* End of RecyclerView Adapter class **********************************************************
}
Here is the Dialog class:
public class DeleteCompetitorDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
final GlobalCompetitorsList mCompetitorsList = GlobalCompetitorsList.get();
return new AlertDialog.Builder(getActivity())
.setTitle("Delete this Competitor?")
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// remove from the master_competitors.json file by overwriting the original file with the new
// global list
File file = new File("data/data/com.checkinsystems.ez_score/files/master_competitors.json");
if (file.exists()) {
FileOutputStream fos = null;
try {
String jsonString = new Gson().toJson(mCompetitorsList);
fos = getActivity().openFileOutput("master_competitors.json", getActivity().MODE_PRIVATE);
fos.write(jsonString.getBytes());
// somehow access the list from the calling activity to remove the item
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert fos != null;
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
})
.create();
}
}
And if it helps to understand my code, here is the Singleton class
public class GlobalCompetitorsList {
public static GlobalCompetitorsList sGlobalCompetitorsList;
public static List<Competitor> sCompetitors;
public static GlobalCompetitorsList get() {
if(sGlobalCompetitorsList == null){
return new GlobalCompetitorsList();
} else {
return sGlobalCompetitorsList;
}
}
private GlobalCompetitorsList() {
File file = new File("data/data/com.checkinsystems.ez_score/files/master_competitors.json");
String jsonString;
if(file.exists()){
BufferedReader reader = null;
List<Competitor> list;
sCompetitors = new ArrayList<>();
try {
reader = new BufferedReader(new FileReader(file));
jsonString = reader.readLine();
Type compType = new TypeToken<List<Competitor>>(){}.getType();
list = new Gson().fromJson(jsonString, compType);
addCompetitors(list);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert reader != null;
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
sCompetitors = new ArrayList<>();
}
}
public void addCompetitor(Competitor c){
sCompetitors.add(c);
}
public static void addCompetitors(List<Competitor> c){
sCompetitors.addAll(c);
}
public static List<Competitor> getCompetitors(){
return sCompetitors;
}
}
Simple just create a constructor for the Dialog that you are using
public DeleteCompetitorDialogFragment(IMyListenerCallback listener){
mListener = listener;
}
later on//
if(listener != null){
listener.doWhatYouNeed(stuffToPass);
}
Then make an interface class
public interface IMyListenerCallback{
void doWhatYouNeed(Object stuffToPass);
}
//then in your calling activity
public class MainActivity extends AppCompatActivity implements IMyListenerCallback{
private void launchDialog(){
new DeleteCompetitorDialogFragment(this).show();
}
#Override
public void doWhatYouNeed(Object stuffToPass){
}
}
Of course this is pseduo code and not tested, but hopefully you get the picture. Goodluck.

ListView only updates after orientation change

I am attempting to enact the Parcelable pattern to save and restore my ListView data on orientation changes.
The problem is, the ListView will only update once I do an orientation change. It will not update otherwise. It used to work just fine, until I started implementing Parcelable.
All help is greatly appreciated!
My fragment class is copied below, but can also be accessed here on GitHub:
public class TrackActivityFragment extends Fragment {
private IconicAdapter trackResultListViewAdapter = null;
private String artistId = null;
private final String LOG_TAG = TrackActivityFragment.class.getSimpleName();
public TrackActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ArrayList<TrackParcelable> trackParcelables = null;
View rootView = inflater.inflate(R.layout.fragment_track, container, false);
Intent intent = getActivity().getIntent();
if(intent != null && intent.hasExtra(Intent.EXTRA_SHORTCUT_NAME)) {
artistId = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
}
if(savedInstanceState == null || !savedInstanceState.containsKey("tracks_key")) {
trackParcelables = new ArrayList<TrackParcelable>();
performSearch(artistId);
}
else {
trackParcelables = savedInstanceState.getParcelableArrayList("tracks_key");
}
ListView listView = (ListView) rootView.findViewById(R.id.listViewOfTopTracks);
trackResultListViewAdapter = new IconicAdapter(trackParcelables,
getTrackNamesFromParcelables(trackParcelables));
listView.setAdapter(trackResultListViewAdapter);
return rootView;
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("tracks_key",
trackResultListViewAdapter.getTrackParcelables());
super.onSaveInstanceState(outState);
}
private ArrayList<String> getTrackNamesFromParcelables(ArrayList<TrackParcelable>
trackParcelables){
ArrayList<String> trackNames = new ArrayList<>();
for(TrackParcelable element : trackParcelables){
trackNames.add(element.name);
}
return trackNames;
}
private void performSearch(String artistId) {
SpotifyApi api = new SpotifyApi();
SpotifyService spotify = api.getService();
Map<String, Object> options = new HashMap<>();
options.put("country", "US");
spotify.getArtistTopTrack(artistId, options, new Callback<Tracks>() {
#Override
public void success(Tracks tracks, Response response) {
final ArrayList<TrackParcelable> trackParcelables =
new ArrayList<TrackParcelable>();
for (Track track : tracks.tracks) {
trackParcelables.add(new TrackParcelable(track.name,track.album.name,
track.album.images.get(0).url,track.preview_url));
}
trackResultListViewAdapter.swapItems(trackParcelables);
Log.d(LOG_TAG,trackParcelables.toString());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if(trackParcelables.size()==0){
Toast.makeText(getActivity(),
getString(R.string.no_tracks_found_toast),
Toast.LENGTH_SHORT).show();
}
trackResultListViewAdapter.notifyDataSetChanged();
}
});
}
#Override
public void failure(RetrofitError error) {
}
});
}
//This ViewHolder Pattern is from Busy Android Coder's Guide page 274 of book version 6.7
class ViewHolder {
ImageView icon=null;
TextView trackName=null;
TextView trackAlbum=null;
ViewHolder(View row) {
this.icon = (ImageView)row.findViewById(R.id.imageViewAlbum);
this.trackName = (TextView)row.findViewById(R.id.textViewTrackTitle);
this.trackAlbum = (TextView)row.findViewById(R.id.textViewTrackAlbum);
}
}
//This IconicAdapter Pattern is from Busy Android Coder's Guide page 272 of book version 6.7
class IconicAdapter extends ArrayAdapter<String> {
private ArrayList<TrackParcelable> trackParcelables;
public IconicAdapter(ArrayList<TrackParcelable> trackParcelables,
ArrayList<String> trackNames) {
super(getActivity(), R.layout.list_item_top_tracks, R.id.textViewTrackTitle
, trackNames);
this.trackParcelables = trackParcelables;
}
public void swapItems(ArrayList<TrackParcelable> trackParcelables) {
this.trackParcelables = trackParcelables;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder)row.getTag();
if (holder==null) {
holder=new ViewHolder(row);
row.setTag(holder);
}
Picasso.with(getActivity()).load(trackParcelables.get(position).albumImageUrl)
.into(holder.icon);
TextView trackAlbumTextView = (TextView)row.findViewById(R.id.textViewTrackAlbum);
trackAlbumTextView.setText(trackParcelables.get(position).albumName);
return row;
}
public ArrayList<TrackParcelable> getTrackParcelables(){
return trackParcelables;
}
}
The issue is that IconicAdapter is only tracking changes in trackNames, not in ArrayList <TrackParcelable> trackParcelables.
To fix this, I added a a member variable in my IconicAdapter for the trackNames and set this in the constructor like so:
private ArrayList<TrackParcelable> trackParcelables;
private ArrayList <String> trackNames;
public IconicAdapter(ArrayList<TrackParcelable> trackParcelables,
ArrayList<String> trackNames) {
super(getActivity(), R.layout.list_item_top_tracks, R.id.textViewTrackTitle
, trackNames);
this.trackNames = trackNames;
this.trackParcelables = trackParcelables;
}
Then, I edited my swapItems to update my ListView data like so:
public void swapItems(ArrayList<TrackParcelable> trackParcelables) {
this.trackParcelables = trackParcelables;
trackNames.clear();
trackNames.addAll(getTrackNamesFromParcelables(trackParcelables));
}

SearchView CSV ArrayList

I just started to program for Android.
I'm building this app for my internship but I'm stock with the search function.
I have a CVS file were I set the value in a ArrayList, for this I build a CSV adapter and call this adapter in my Fragment. Now everything works fine I get my list with all the values I want, the problem is the list consist of 1000 records. This is why I want to implement a searchview so that the user can search for the desire value.
Now I want when the user choose the search and starts typing the Arrylist is searched and starts to filter the possible options in the list. This way when the desire value is shown the user can select this one.
I've been trying to do this 3 days already, I know I have to do something in the onQueryTextChange and onQueryTextsubmit. But so far no luck :(
Can someone help me solve this please I would really appreciate it. Tnx in advance.
public class CSVAdapter extends ArrayAdapter<airports> {
Context ctx;
public CSVAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
//Store a reference to the Context so we can use it to load a file from Assets.
this.ctx = context;
//Load the data.
loadArrayFromFile();
}
#Override
public View getView(final int pos, View convertView, final ViewGroup parent){
RelativeLayout row = (RelativeLayout)convertView;
if(null == row){
//No recycled View, we have to inflate one.
LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = (RelativeLayout)inflater.inflate(R.layout.departure_point_fragment, null);
}
TextView anameTxt = (TextView)row.findViewById(R.id.airport_name);
TextView acityTxt = (TextView)row.findViewById(R.id.airport_city);
TextView acountryTxt = (TextView)row.findViewById(R.id.airport_country);
TextView icaoTxt = (TextView)row.findViewById(R.id.airport_code);
anameTxt.setText(getItem(pos).getAname());
acityTxt.setText(getItem(pos).getAcity());
acountryTxt.setText(getItem(pos).getAcountry());
icaoTxt.setText(getItem(pos).getIcao());
return row;
}
private void loadArrayFromFile(){
try {
// Get input stream and Buffered Reader for our data file.
InputStream is = ctx.getAssets().open("airports.csv");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
//Read each line
while ((line = reader.readLine()) != null) {
//Split to separate the name from the capital
String[] RowData = line.split(",");
//Create a State object for this row's data.
airports cur = new airports();
cur.setAname(RowData[0]);
cur.setAcity(RowData[1]);
cur.setAcountry(RowData[2]);
cur.setIcao(RowData[3]);
cur.setLat(RowData[4]);
cur.setLon(RowData[5]);
cur.setAltitude(RowData[6]);
cur.setTimezone(RowData[7]);
cur.setDst(RowData[8]);
//Add the State object to the ArrayList (in this case we are the ArrayList).
this.add(cur);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class airports {
private String aname;
private String acity;
private String acountry;
private String icao;
private String lat;
private String lon;
private String altitude;
private String timezone;
private String dst;
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public String getAcity() {
return acity;
}
public void setAcity(String acity) {
this.acity = acity;
}
public String getAcountry() {
return acountry;
}
public void setAcountry(String acountry) {
this.acountry = acountry;
}
public String getIcao() {
return icao;
}
public void setIcao(String icao) {
this.icao = icao;
}
public String getLat() {
return lat;
}
public void setLat(String lat) {
this.lat = lat;
}
public String getLon() {
return lon;
}
public void setLon(String lon) {
this.lon = lon;
}
public String getAltitude() {
return altitude;
}
public void setAltitude(String altitude) {
this.altitude = altitude;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public String getDst() {
return dst;
}
public void setDst(String dst) {
this.dst = dst;
}
}
public class departurePointFragment extends SherlockListFragment implements SearchView.OnQueryTextListener{
private CSVAdapter mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.listview, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); getSherlockActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSherlockActivity().getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
setHasOptionsMenu(true);
mAdapter =new CSVAdapter(getActivity(), -1);
setListAdapter(mAdapter);
getListView();
setRetainInstance(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.searching, menu);
MenuItem item = menu.findItem(R.id.menu_search);
SearchView itemview = (SearchView) item.getActionView();
// Execute this when searching
itemview.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
Log.d("Nicola", "2");
}
#Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String query) {
Log.d("Nicola", "100");
return true;
}
}
Took a while to figure this out, but here it goes :)
Add this to your adapter:
ArrayList<airports> airportsArray = new ArrayList<airports>();
public ArrayList<airports> getAirportsArray()
{
return airportsArray;
}
(you can rightclick on the ArrayList declaration, the choose Source->Generate Getters and Setters)
After reading the CSV file you can add these objects to the newly created ArrayList, changing:
this.add(cur);
to
this.add(cur);
airportsArray.add(cur);
Then in your fragment, in the onQueryTextChange method, do the following:
this.mAdapter.clear(); // This clears the existing list
// Loop through the airports
for (airports item : mAdapter.getAirportsArray())
{
// Does the name contains what you are searching for?
// You can add more criteria here using the || (OR) operator
if (item.getAname().contains(query))
{
// If so, add it
mAdapter.add(item);
}
}
mAdapter.notifyDataSetChanged(); // Notify the adapter that the dataset changed
return true;
Hope that helps, good luck!

Categories

Resources