Adding search functionality inside a tabbed-acitivity in Android - android

I've checked this question on SO where I basically have the same issue.
The difference is that I am not using an Adapter Class in my project, I only have a TabActivity.java (android studio default) that populated my fragments.
I have already followed all the steps in the questions answer however I do not understand the third step.
3.Code of Adapter(Adapter_Contacts.java in my case)
Where should I put this code because in my case I do not use any Adapter Class
this is my fragment adapter inside tabactivity.java
public class SectionsPagerAdapter extends FragmentPagerAdapter{
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position){
case 0:
return new BrowseTitle();
case 1:
return new ChatHistory();
default:
break;
}
return null;
}
#Override
public int getCount() {
// Show 2 total pages.
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
}
and this is one of my fragment that populated inside tabactivity
public class BrowseTitle extends Fragment {
private DatabaseReference mRootRef;
private ListView listView;
private ArrayAdapter<String> arrayAdapter;
private ArrayList<String> list_of_thread = new ArrayList<>();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
//Overriden method onCreateView
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_browse_title, container, false);
//this is the logic
mRootRef = FirebaseDatabase.getInstance().getReference().child("tdesc");
listView = (ListView) v.findViewById(R.id.titleList);
arrayAdapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),android.R.layout.simple_list_item_1,list_of_thread){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view =super.getView(position, convertView, parent);
TextView textView=(TextView) view.findViewById(android.R.id.text1);
//changin text color
textView.setTextColor(Color.BLACK);
return view;
}
};
listView.setAdapter(arrayAdapter);
public void beginSearch(String query) {
Log.e("QueryFragment", query);
arrayAdapter.getFilter().filter(query);
}
}
Is there a way I can implement this correctly?

Related

Refresh current fragment in tabbed layout viewpager

I am trying to refresh the current fragment in the tabbed layout of my viewpager. I have one fragment (UserProgressFragment) that creates the ViewPager and sets the adapter (UserProgressAdapter) along with creating tabbed layout.
In my UserProgressAdapter, in the getItem() method I am returning two other fragments, (UserWeightTrackerFragment and UserCalorieCounterFragment) based on which tab i am on.
My issue is how do i refresh the fragment and update its content/view from the UserCalorieCounterFragment on a button click, because access to the viewpager and adapter are set in the UserProgressFragment? I have considered notifyDataChange for the adapter but i dont know how to call this from this class as it is set up on the UserProgressFragment class. The purpose of wanting to refresh this page is to update a specific view which is a chart, if context is needed.
I have attached the code below:
UserProgressFragment
public class UserProgressFragment extends Fragment{
public static UserProgressFragment newInstance() {
return new UserProgressFragment();
}
public UserProgressFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_progress, container, false);
ViewPager viewPager = view.findViewById(R.id.progress_viewpager);
viewPager.setAdapter(new UserProgressTabsAdapter(getChildFragmentManager()));
TabLayout tabLayout = view.findViewById(R.id.progress_sliding_tabs);
tabLayout.setupWithViewPager(viewPager, true);
return view;
}
}
UserProgressTabsAdapter
public class UserProgressTabsAdapter extends FragmentStatePagerAdapter {
private static final int PAGE_COUNT = 2;
private String tabTitles[] = new String[]{"Weight Tracker", "Calorie Counter"};
public UserProgressTabsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return UserWeightTrackerFragment.newInstance(position);
case 1:
return UserCalorieCounterFragment.newInstance(position + 1);
}
return null;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
UserCalorieCounterFragment (need to refresh this one)
public class UserCalorieCounterFragment extends Fragment implements View.OnClickListener, AdapterView.OnItemSelectedListener {
public static final String ARG_PAGE = "ARG_PAGE";
public static UserCalorieCounterFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
UserCalorieCounterFragment fragment = new UserCalorieCounterFragment();
fragment.setArguments(args);
return fragment;
}
public UserCalorieCounterFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int mPage = getArguments().getInt(ARG_PAGE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_calorie_counter, container, false);
Button mAddCalories = view.findViewById(R.id.btn_add_calorie);
mAddCalories.setOnClickListener(this);
return view;
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_add_calorie:
//REFRESH/UPDATE HERE
break;
}
}
You can create a public method in your fragment which contains the view pager which will contain the notifyDataSetChanged() function. And in the view pager fragment/item, you can call getParentFragment() and type cast it to your parent/first fragment and access that public method to notifyDataSetChanged().

ViewPager [FragmentPagerAdapter] inside ListView

i'm trying to put ViewPager into ListView
here the code of ListView AdapterClass:
public class AdapterPager extends BaseAdapter {
.....
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.component_pager, parent, false);
new ViewHolder(view, itemData.get(position));
}
return view;
}
View Holder:
private class ViewHolder {
ViewPager pager;
PagerAdapter pagerAdapter;
public ViewHolder(View view, ModelItem model){
pager = (ViewPager) view.findViewById(R.id.pager);
pager.setId(model.getId()); /// uniq ID
pagerAdapter = new MyFragmentPagerAdapter(((FragmentActivity)view.getContext()).getSupportFragmentManager());
pager.setAdapter(pagerAdapter);
}
then, Pager Adapter:
static final int PAGE_COUNT = 2;
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return FragmentComponentPager.newInstance(position, mModel);
}
#Override
public float getPageWidth(int position) {
float f_width = 1f;
return f_width;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
and, the last, Pager Fragment:
public class FragmentComponentPager extends Fragment {
static final String ARGUMENT_PAGE_NUMBER = "arg_page_number";
static final String ARGUMENT_NAME = "arg_name";
int pageNumber;
public static FragmentComponentPager newInstance(int page, ModelItem data) {
FragmentComponentPager pageFragment = new FragmentComponentPager();
Bundle arguments = new Bundle();
arguments.putInt(ARGUMENT_PAGE_NUMBER, page);
if (data != null){
arguments.putString(ARGUMENT_NAME, data.getName());
}
pageFragment.setArguments(arguments);
return pageFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pageNumber = getArguments().getInt(ARGUMENT_PAGE_NUMBER);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.component_list, null);
TextView tvTitle = (TextView) view.findViewById(R.id.tvTitle);
tvTitle.setText(getArguments().getString(ARGUMENT_NAME));
return view;
}
}
when i run it ListView shows all items that i've added, but all of them, except the last one, with empty ViewPager.
and, if i removed pager.setId(model.getId()); the first item shows view pager, and the others empty.
guess that smth wrong with FragmentManager, but have no idea how deal with it :(
In your ViewHolder you need to call getChildFragmentManager instead of getSupportFragmentManager.

ViewPager inside FragmentDialog Height always equals to 0

I know a lot of questions just like this one have been asked, but I didn't see any real similarity to this case.
I'm using the android android.support.v4.app.DialogFragment and android.support.v4.app.Fragment
I'm trying show web service response in a Popup View containing swipe views, so I'm using a DialogFragment and inside it is a ViewPager, and of course there is a ListView inside each fragment in the ViewPager to show the results.
Code:Activity that shows the Dialog
new ResultFragmentDialog().show(getSupportFragmentManager(), TAG_RESULT_DIALOG_FRAGMENT);
ResultFragmentDialog code:
public class ResultFragmentDialog extends DialogFragment {
private View view;
private ViewPager pager;
private FragmentsResultAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.dialog_result, container, false);
Dialog dialog = getDialog();
dialog.setOnShowListener(new OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
//Im creating the adapter here because if I don't there will be an IllegalArgumentException: No view found for id for fragment ..
pager = (ViewPager) view.findViewById(R.id.pager);
adapter = new FragmentsResultAdapter(getChildFragmentManager());
pager.setAdapter(adapter);
}
});
return view;
}
private class FragmentsResultAdapter extends FragmentStatePagerAdapter {
private ResultListDialogFragment firstFragment;
private ResultListDialogFragment secondFragment;
public FragmentsResultAdapter(FragmentManager fm) {
super(fm);
firstFragment = new ResultListDialogFragment();
secondFragment = new ResultListDialogFragment();
}
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return false;
}
#Override
public CharSequence getPageTitle(int position) {
return position == 0 ? "First" : "Second";
}
#Override
public Fragment getItem(int position) {
return position == 0 ? firstFragment : secondFragment;
}
#Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
}
}
ResultListDialogFragment code:
public class ResultListDialogFragment extends Fragment {
private View view;
private ListView list;
private ResultAdapter adapter;
private ResponseMultipleItems result = new ResponseMultipleItems();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_dialog_result_lst, container, false);
list = (ListView) view.findViewById(R.id.lstResult);
list.setOnItemClickListener(adapter);
adapter = new ResultAdapter(getActivity());
list.setAdapter(adapter);
return view;
}
public void loadResult(List<Item> result) {
result.setResult(result);
adapter.notifyDataSetChanged();
}
public void clear() {
result.getResult().clear();
notifyDataSetChanged();
}
private class ResultAdapter extends BaseAdapter implements OnItemClickListener {
private Context context;
private ResultItem item;
private Holder holder;
public ResultAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return result.getResult().size();
}
#Override
public Object getItem(int position) {
return result.getResult().get(position);
}
#Override
public long getItemId(int position) {
return result.getResult().get(position).getId();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
item = result.getResult().get(position);
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_result, parent, false);
holder = new Holder();
holder.txt = (TextView) convertView.findViewById(R.id.txtTitle);
convertView.setTag(holder);
}
holder = (Holder) convertView.getTag();
if (position == result.getResult().size() - 1 && result.isHasMore()) {
holder.txt.setText("Load more");
} else {
holder.txt.setText(item.getTitle());
}
return convertView;
}
private class Holder {
TextView txt;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
}
ViewPager code in layout file:
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
ListView code in layout file:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lstResult"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And finally the problem is that the created ListView inside the fragment has a height of 0 !!!
How did I know that the lists in both fragments have the height of zero? I didn't know at the beginning, but the public View getView(int position, View convertView, ViewGroup parent) inside the ResultAdapter is not getting called, while the public int getCount() all ways gets called after the notifyDataSetChanged() is called.
So I used the HeirarchyViewer and it shows DialogFragment has a normal height, the NoSaveStateFrameLayout for each fragment getHeight() attr from the heirarchyviewer shows 0, and the ListView inside the NoSaveStateFrameLayout also have a 0 height.
The Dialog is displayed successfully and I can swipe between two invisible views !!
The background code I didn't write successfully fetches the content and passes them to the adapter, yet the public View getView(int position, View convertView, ViewGroup parent) is not triggered !!
tried to use wrap_content instead of match_parent didn't work.
tried getLayoutParams().height = 100 after creating the listviews also didn't work.
tried setting a new LayoutParam with new width and height, also didn't work.
tried to use a Dialog instead of DialogFragment also didn't work.

Two instances of the same ListFragment in one FragmentActivity using ViewPager

I have a FragmentActivity that uses a ViewPager to flip left and right through pages of data (two ListFragments).
public class StopsActivity extends FragmentActivity {
private ViewPager mViewPager;
private PagerTabStrip mPagerTabStrip;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stops);
mPagerTabStrip =(PagerTabStrip)findViewById(R.id.pager_header);
mViewPager = (ViewPager)findViewById(R.id.pager);
mPagerTabStrip.setDrawFullUnderline(true);
mPagerTabStrip.setTabIndicatorColorResource(R.color.pagerTabStrip);
mViewPager.setAdapter(new StopsAdapter(getSupportFragmentManager()));
mViewPager.setCurrentItem(0);
}
private class StopsAdapter extends FragmentPagerAdapter {
public StopsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return StopsFragment.newInstance(routename, Stop.FORWARD);
case 1:
return StopsFragment.newInstance(routename, Stop.BACKWARD);
}
return null;
}
#Override
public int getCount() { return 2;}
#Override
public CharSequence getPageTitle(int position) { /* implementation ... */}
}
}
Everything runs ok, but I think that the instantation of the second StopFragment invalidate the data of the first one when getItem is called.
public class StopsFragment extends ListFragment {
private StopsAdapter mStopsAdapter;
private ListView mListView;
private String routename;
private int direction;
public static StopsFragment newInstance(String routename, int direction) {
StopsFragment stopsFragment = new StopsFragment();
// Supply arguments
Bundle args = new Bundle();
args.putString("routename", routename);
args.putInt("direction", direction);
stopsFragment.setArguments(args);
return stopsFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the adapter
ArrayList<Stop> stops = ...
mStopsAdapter = new StopsAdapter(getActivity(), stops);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) {
View rootView = inflater.inflate(R.layout.fragment_stops, container, false);
// Attach the adapter
mListView = (ListView) rootView.findViewById(android.R.id.list);
mListView.setAdapter(mStopsAdapter);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
The page "IDA" corresponds to StopFragment with argument Stop.FORWARD and the page "VUELTA" corresponds the StopFragment with argument Stop.BACKWARD. As you can see in the images below, just one of them (the last one instantiate) is populated:
What I'm doing wrong?
EDIT
This is StopsAdapter
class StopsAdapter extends BaseAdapter {
private ArrayList<Stop> stops;
private LayoutInflater inflater;
public StopsAdapter(Context context, ArrayList<Stop> stops) {
this.stops = stops;
this.inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return stops.size();
}
#Override
public Object getItem(int position) {
return stops.get(position);
}
#Override
public long getItemId(int position) {
return (long)position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_stop, parent, false);
}
TextView name = (TextView)convertView.findViewById(R.id.tvStopName);
TextView description = (TextView)convertView.findViewById(R.id.tvStopDescription);
Stop stop = (Stop)getItem(position);
name.setText(stop.name);
if (stop.info != null) {
description.setText(stop.info);
}
return convertView;
}
}
Ok, my fault. The code that was giving me problems is the only that I haven't posted (ArrayList<Stop> stops = ...). The code about Fragments and ViewPager works correctly.

Populate ListView after Button Click in Fragments

So I'm trying populate a ListView in one Fragment after adding Text in an EditText field after a button click in another Fragment.
My java coding skills are pretty bad, so any code suggestions would help me a lot.
I hope this makes sense.
Here's my code.
public class FieldsActivity extends FragmentActivity {
private static final int NUMBER_OF_PAGES = 3;
ViewPager mPager;
MyFragmentPagerAdapter mMyFragmentPagerAdapter;
ArrayList<String>siteList = new ArrayList<String>();
CustomAdapter ca = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.fields);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.topbar);
mPager = (ViewPager) findViewById(R.id.fieldspager);
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mMyFragmentPagerAdapter);
mPager.setCurrentItem(1);
}
Where my ListView is.
public class AddSite extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RelativeLayout mRelativeLayout = (RelativeLayout) inflater.inflate(R.layout.add_site, container, false);
Button addSiteButton = (Button) mRelativeLayout.findViewById(R.id.addSiteButton);
addSiteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mPager.setCurrentItem(2, true);
}
});
ListView lv = (ListView) findViewById(android.R.id.list);
CustomAdapter ca = new CustomAdapter();
lv.setAdapter(ca);
return mRelativeLayout;
}
class CustomAdapter extends ArrayAdapter<String> {
CustomAdapter() {
super(FieldsActivity.this, android.R.layout.simple_list_item_1, siteList);
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater=getLayoutInflater();
row = inflater.inflate(R.layout.list_row, null);
}
((TextView)row.findViewById(R.id.textViewId)).setText(siteList.get(position));
}
return row;
}
}
Where the Button and EditText is.
public class CreateSite extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RelativeLayout mRelativeLayout = (RelativeLayout) inflater.inflate(R.layout.main, container, false);
final EditText siteEditText = (EditText)findViewById(R.id.siteEditText);
Button signInButton = (Button) mRelativeLayout.findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //Click this button and add to ListView in class AddSite
siteList.add(0, siteEditText.getText().toString());
ca.notifyDataSetChanged(); //(Bundle) cannot be applied
siteEditText.setText("");
mPager.setCurrentItem(1, true);
}
});
return mRelativeLayout;
}
}
While all in a FragmentPagerAdapter
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: return new SettingFields();
case 1: return new AddSite();
case 2: return new CreateSite();
}
return null;
}
#Override
public int getCount() {
return NUMBER_OF_PAGES;
}
}
}
So I've commented the errors that are shown.
Hope this makes sense.
Let me know if you need to see anything else.
Thanks in advance!
Your fragments should not talk directly to each other. Instead, each fragment should report the Activity, and the Activity can decide what to do with that action.
The normal way to do this is to have a Fragment define an interface, and have the Activity implement that interface. Then there is a method that the Fragment can call, on the Activity. Then the Activity can call a method on the other Fragment to make it perform some action.
See the documentation on Fragment communication.

Categories

Resources