public Fragment getItem(int position) {
ArrayList <Fragment> fragments = new ArrayList <Fragment>();
Fragment1 obj1=new Fragment1();
Fragment2 obj2=new Fragment2();
Fragment3 obj3=new Fragment3();
Fragment4 obj4=new Fragment4();
fragments.add(obj1);
fragments.add(obj2);
fragments.add(obj3);
fragments.add(obj4);
Fragment fragment = fragments.get(position);
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
So using these objects at the runtime through getItem() method I wanna access the functions in the fragments?So plz anyone help me out.
You can cast the fragment returned to the one you need to.
YourClass fragmentGenerator = new YourClass();
((Fragment1)fragmentGenerator.getItem(0)).yourMethod1();
((Fragment2)fragmentGenerator.getItem(1)).yourMethod2();
Related
I want my firebase database link to be updated depending on what the user keys in inside the searchview but the link is not updated unless I open another activity and jump back to it.I have attacked my code in the bottom. So how do I refresh it automatically ?
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query) {
query = sv.getQuery().toString();
Toast.makeText(MainMenu.this,query, Toast.LENGTH_SHORT).show();
makeItem();
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
public void makeItem ()
{
lv = findViewById(R.id.listView);
db = FirebaseDatabase.getInstance().getReferenceFromUrl("https://vsem-inventory.firebaseio.com/ItemList").orderByChild("ProductName").startAt(query).endAt(query+"\uf8ff");
FirebaseListOptions<ItemObject> options = new FirebaseListOptions.Builder<ItemObject>()
.setLayout(R.layout.content_main_menu_list)
.setQuery(db,ItemObject.class)
.build();
mAdapter = new FirebaseListAdapter<ItemObject>(options) {
#Override
protected void populateView(#NonNull View v, #NonNull ItemObject model, int position) {
final TextView tvAmount = v.findViewById(R.id.amount);
final TextView tvName = v.findViewById(R.id.name);
final TextView tvSerial = v.findViewById(R.id.serialNo);
final TextView tvSupplier = v.findViewById(R.id.supplierName);
final ImageView more = v.findViewById(R.id.more);
ImageView statusimg = v.findViewById(R.id.status);
Drawable paidIcon = v.getResources().getDrawable(R.drawable.succes);
Drawable lateIcon = v.getResources().getDrawable(R.drawable.late);
tvName.setText(model.getProductName());
tvSerial.setText(model.getSerialNo());
tvAmount.setText(model.getQuantity());
tvSupplier.setText(model.getModel());
final String Remarks = model.getRemarks();
final String cat = model.getCategory();
if(model.getQuantity().equals("0"))
statusimg.setImageDrawable(lateIcon);
else
statusimg.setImageDrawable(paidIcon);
more.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String serialNo = tvSerial.getText().toString();
String itemName = tvName.getText().toString();
String quan = tvAmount.getText().toString();
String supplier = tvSupplier.getText().toString();
showMenu(itemName,more,serialNo,quan,supplier,cat,Remarks);
}
});
}
};
lv.setAdapter(mAdapter);
}
The standard way is to call notifyDataSetChanged() after setting your adapter to your list view
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
mAdapter.notifyDataSetChanged();
Although I have seen some situations where only using this does not work and must be followed by these 2 commands.
lv.invalidateViews();
lv.scrollBy(0, 0);
And if all else comes to fail falling back on destroying and redrawing the list view might be your only viable option.
lv.destroyDrawingCache();
lv.setVisibility(ListView.INVISIBLE);
lv.setVisibility(ListView.VISIBLE);
EDIT : After looking at it a while more I just noticed you're missing listeners for your firebase. I assume you already have them somewhere as you already have the list but failing your refresh functions, what you can try is restarting the listeners whenever you're done with a query.
lv.setAdapter(mAdapter);
mAdapter.stopListening();
mAdapter.startListening();
I have the following code :
List<Object> result = new ArrayList<Object>();
//Object is actually a Map<String,Object>
return Maps.uniqueIndex(result, new Function<Map<String, Object>, Long>() {
#Override
public Long apply(Map<String, Object> input) {
return (Long) input.remove("id");
}
});
I get compilation error.
The method uniqueIndex(Iterable<V>, Function<? super V,K>) in the type Maps is not applicable for the arguments (List, new Function<Map<String,Object>,Long>(){}).
How do I rewrite this piece of code such that I don't get into this issue?
The first generic parameter of Function must match the type of elements held by List.
So, if you have a List<T>, a Function will be used for doing something with elements from that List, hence it needs to be a Function<T, WHATEVER>.
So, in your case:
List<Object> result = new ArrayList<>();
Maps.uniqueIndex(result, new Function<Object, WHATEVER>() {
#Nullable
#Override
public WHATEVER apply(#Nullable Object s) {
return null; // do whatever you want here
}
});
If you want to store Map<String,Object> in a List why not use List<Map<String,Object>>?
List<Map<String,Object>> result = new ArrayList<>();
Maps.uniqueIndex(result, new Function<Map<String,Object>, WHATEVER>() {
#Nullable
#Override
public WHATEVER apply(#Nullable Map<String,Object> s) {
return null; // do whatever you want here
}
});
I have an Activity A that consists of Fragment A. Inside Fragment A, I start Activity B with startActivityForResult(). When I receive the result from Activity B, all views values in Fragment A that had already been set before return to their default values. How to retain the all views values in Fragment A?
Below is the implementation:
public class MainFragment extends Fragment {
public MainFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView = (ListView) getActivity().findViewById(R.id.xlistview);
xItemArrayList = new ArrayList<XItem>();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.menu_item_add:
initialiseList();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void initialiseList(){
xListAdapter = new xListAdapter(getContext(), R.layout.item_list, xItemArrayList);
xListAdapter.setxListListener(new xListListener() {
#Override
public void onClickStart(View view) {
openAutocompleteActivity(Constant.VIEW_START);
}
});
xListView.setAdapter(xListAdapter);
}
private void openAutocompleteActivity(int selectedView) {
this.selectedView = selectedView;
try {
// The autocomplete activity requires Google Play Services to be available. The intent
// builder checks this and throws an exception if it is not the case.
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN).build(getActivity());
startActivityForResult(intent, Constant.REQUEST_CODE_AUTOCOMPLETE);
} catch (GooglePlayServicesRepairableException e) {
// Indicates that Google Play Services is either not installed or not up to date. Prompt the user to correct the issue.
GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), e.getConnectionStatusCode(), 0 ).show();
} catch (GooglePlayServicesNotAvailableException e) {
// Indicates that Google Play Services is not available and the problem is not easily resolvable.
String message = "Google Play Services is not available: " + GoogleApiAvailability.getInstance().getErrorString(e.errorCode);
Log.e(Constant.TAG_ERROR, message);
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check that the result was from the autocomplete widget.
if (requestCode == Constant.REQUEST_CODE_AUTOCOMPLETE) {
if (resultCode == Constant.RESULT_OK) {
// Get the user's selected place from the Intent.
Place place = PlaceAutocomplete.getPlace(getActivity(), data);
if (selectedView == Constant.VIEW_START){
start = place;
((TextView)xListView.getChildAt(0).findViewById(R.id.textview_start)).setText(start.getName());
}else if (selectedView == Constant.VIEW_LAST){
last = place;
((TextView)xListView.getChildAt(0).findViewById(R.id.textview_last)).setText(last.getName());
}
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(getActivity(), data);
Log.e(Constant.TAG_ERROR, "Error: Status = " + status.toString());
} else if (resultCode == Constant.RESULT_CANCELED) {
// Indicates that the activity closed before a selection was made. For example if
// the user pressed the back button.
}
}
}
There are two views in R.layout.item_list, R.id.textview_start and R.id.textview_last. On select each of the view, Activity B will start and on finish Activity B, the result will be displayed on the view itself. However, every time Activity B starts and finishes, previous values of the two views disappear and return to default. I have tried SavedInstanceState, but it does not work. It seems when Activity B returns to Activity A (with Fragment A in it), system goes to OnResume() of Fragment A without going to onCreatedView() of Fragment A.
You can use 2 method:
1st: use sharedpreferences to store the data. Now this data is accessible next time also the app is used. So after displaying the old data, just reset the data in sharepreferences to blank.
2nd: use bundle to transfer data to the activity and then just retrieve the same back.
Use a bundle to transfer data from one activity to another activity
Bundle bundle = new Bundle();
bundle.putString("KEY_NAME", "Abrakadabra");
Intent i = new Intent(this, MyActivityName.class);
i.putExtras(bundle);
startActivity(i) <-- new activity started
Then in the receiving activity: Put this code in the onCreate method
Bundle bundle = getIntent().getExtras();
String stringdata = bundle.getString("KEY_NAME");
To pass data from activity to fragment: Put this code anywhere
Bundle bundle = new Bundle();
bundle.putString("KEY_NAME", "Abrakadabra");
MyFragment myfragment = new MyFragment();
myfragment.setArguments(bundle);
Then in the onCreateView method of the fragment add this code
Bundle args = getArguments();
String stringdata = args.getString("KEY_NAME");
Since Fragment A is waiting for Activity B's result, Activity A (where Fragment A is) will go to pause state. When Activity B returns results, Fragment A will resumes without going through onActivityCreated(). Thus, saving instance state will not work. Currently, the only solution I can think of is as below.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check that the result was from the autocomplete widget.
if (requestCode == Constant.REQUEST_CODE_AUTOCOMPLETE) {
if (resultCode == Constant.RESULT_OK) {
// Get the user's selected place from the Intent.
Place place = PlaceAutocomplete.getPlace(getActivity(), data);
if (selectedView == Constant.VIEW_START){
start = place;
}else if (selectedView == Constant.VIEW_LAST){
last = place;
}
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(getActivity(), data);
Log.e(Constant.TAG_ERROR, "Error: Status = " + status.toString());
} else if (resultCode == Constant.RESULT_CANCELED) {
// Indicates that the activity closed before a selection was made. For example if
// the user pressed the back button.
}
}
if(start!=null)((TextView)xListView.getChildAt(0).findViewById(R.id.textview_start)).setText(start.getName());
if(last!=null)((TextView)xListView.getChildAt(0).findViewById(R.id.textview_last)).setText(last.getName());
}
All the views values are re-set in onActivityResult(). When Activity A/Fragment A goes into pause state, it retains global variables values. Thus, for this implementation to work, start and last must be declared as global variables in Fragment A. Please suggest a better solution, if any.
I am trying to replace fragment with another inside a onItemClick of list view and i want to send a selected item name from list fragment to another fragment but its showing null pointer exception
#Override
public void onItemClick(AdapterView arg0, View view, int position,
long id)
{
try
{
Log.e("----- inside onItemClick -----", citySelected);
MapVisibleFragment newFragment = new MapVisibleFragment();
Bundle args = new Bundle();
args.putString("CITYNAME", citySelected);
newFragment.setArguments(args);
((BaseContainerFragment) getParentFragment()).replaceFragment(
newFragment, true);
} catch (Exception e)
{
e.printStackTrace();
}
}
but the same concept is working inside button click for the below one
try
{
ListFragmentFromDBRecords2 newFragment = new ListFragmentFromDBRecords2();
Bundle args = new Bundle();
args.putStringArrayList("names", allData);
newFragment.setArguments(args);
((BaseContainerFragment) getParentFragment()).replaceFragment(
newFragment, true);
Log.d("--->>>>", allData.toString());
}
catch (Exception e)
{
e.printStackTrace();
}
Based on your comment
((BaseContainerFragment) getParentFragment())
is null for you. Check why getParentFragment() method returns null.
I’m trying to fake http context to test a Controller. My environment is MVC 3 and Moq 4.
So far I have tried a few options including:
a.
var searchController = new MySearchController(_mockResolver.Object.Resolve<IConfiguration>());
var mockContext = new Mock<ControllerContext>();
searchController.ControllerContext = mockContext.Object;
var result = searchController.Render();
b.
var searchController = new MopSearchController(_mockResolver.Object.Resolve<IConfiguration>());
searchController.MockControllerContext();
var result = searchController.Render();
public static class MockHttpHelper
{
public static Mock<HttpContextBase> MockControllerContext(
this Controller controller, string path = null)
{
var mockHttpCtx = MockHttpHelper.MockHttpContext(path);
var requestCtx = new RequestContext(mockHttpCtx.Object, new RouteData());
var controllerCtx = new ControllerContext(requestCtx, controller);
controller.ControllerContext = controllerCtx;
return mockHttpCtx;
}
public static Mock<HttpContextBase> MockHttpContext(string path)
{
var mockHttpCtx = new Mock<HttpContextBase>();
var mockReq = new Mock<HttpRequestBase>();
mockReq.SetupGet(x => x.RequestType).Returns("GET");
mockReq.SetupGet(req => req.Form).Returns(new NameValueCollection());
mockReq.SetupGet(req => req.QueryString).Returns(new NameValueCollection());
mockHttpCtx.SetupGet(x => x.Request).Returns(mockReq.Object);
return mockHttpCtx;
}
}
Neither of these work, I get the exception below. Can anyone point me in the direction of a working example? I’ve seen quite a few questions on the net around the same topic, but given the date (posts from 2008-2010) and MVC version (i.e. 1 and 2) I feel like I’m missing something / or trying to mock more than I need to in MVC3.
System.NullReferenceException : Object reference not set to an instance of an object.
at System.Web.Mvc.ChildActionValueProviderFactory.GetValueProvider(ControllerContext controllerContext)
at System.Web.Mvc.ValueProviderFactoryCollection.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList(IEnumerable`1 source)
at System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext)
at System.Web.Mvc.Controller.TryUpdateModel(TModel model)
Thanks
Yes, all you were really missing, as you've noted, was setting the Controller's ValueProvider. Even though you're using this controller with a Get action but no Post action, the Controller still gets its ValueProvider instantiated upon creation, so you need to do the same thing in your test scenario. Here's the base class that I use when testing my controllers. I use NBehave's NUnit wrapper for unit testing, so ignore the SpecBase reference if you wish
public abstract class MvcSpecBase<T> : SpecBase<T> where T : Controller
{
protected T Controller { get; set; }
protected string RelativePath = string.Empty;
protected string AbsolutePath = string.Empty;
protected void InitialiseController(T controller, NameValueCollection collection, params string[] routePaths)
{
Controller = controller;
var routes = new RouteCollection();
RouteConfig.RegisterRoutes(routes);
var httpContext = ContextHelper.FakeHttpContext(RelativePath, AbsolutePath, routePaths);
var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), Controller);
var urlHelper = new UrlHelper(new RequestContext(httpContext, new RouteData()), routes);
Controller.ControllerContext = context;
Controller.ValueProvider = new NameValueCollectionValueProvider(collection, CultureInfo.CurrentCulture);
Controller.Url = urlHelper;
}
}
Then, in your test, create your controller and then call this line:
InitialiseController(controller, new FormCollection());