I have a viewpager with an adapter that extends FragmentStatePagerAdapter, this has to show some fragment that always repeats the same layout (in whic there is a listView) for every page ... now the problem is how can I update the listView that is currently visible by clicking on a button that is outside of the Fragment? I can refresh only the ones that are in the not visible pages,but not the ones that are displayed or adjacent...
One possible solution is to reset the adapter, but it doesn't seems to be right one, because it' s slow... could you please help me?
public class MainActivity extends FragmentActivity implements OnClickListener{
#Override
protected void onCreate(Bundle arg0) {
// TODO Auto-generated method stub
super.onCreate(arg0);
setContentView(R.layout.layout1);
pagerAdapter = new AdapterPager(getSupportFragmentManager());
ctx=this;
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(pagerAdapter);
pagerTab=(PagerTabStrip) findViewById(R.id.pager_tab_strip);
mViewPager.setCurrentItem(paginaCentrale);
modifica=(ImageView)findViewById(R.id.modifica);
modifica.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
// TODO onClick
switch (arg0.getId()){
case R.id.modifica:
//here I would like to call the method caricaLista() of the fragment
break;
}
}
public static class AdapterPager extends FragmentStatePagerAdapter {
public AdapterPager(FragmentManager fm) {
super(fm);
}
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return super.getItemPosition(object);
}
#Override
public Fragment getItem(int i) {
Fragment fragment;
Bundle args = new Bundle();
args.putInt("position", i);
fragment=new Fragment1();
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 1000;}
#Override
public CharSequence getPageTitle(int i) {
String title=String.valueOf(i);
return title;
}
}
public static class Fragment1 extends Fragment implements OnItemClickListener{
int fragmentPosition;
ListView lv;
List<Lista> lista= new ArrayList<Lista>();
public Fragment1(){
}
public static Fragment1 newInstance(){
return new Fragment1();
}
#Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
caricaLista("")}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle
savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1, container, false);
lv=(ListView) rootView.findViewById(R.id.listViewCompiti);
Bundle args = getArguments();
int position= args.getInt("position");
fragmentPosition=position;
lv.setOnItemClickListener(this);
homeListAdapter= new HomeListAdapterWithCache(ctx,R.layout.list_item_home,lista);
lv.setAdapter(homeListAdapter);
return rootView;
}
You have to store the Current Fragment into your MainActivity , and change every time the page changes.
So you call the method of the current fragments.
Check out how your MainActivity should look like:
public class MainActivity extends FragmentActivity implements OnClickListener{
&Fragment mCurrentFragment;*
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.layout1);
pagerAdapter = new AdapterPager(getSupportFragmentManager());
ctx=this;
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(pagerAdapter);
pagerTab=(PagerTabStrip) findViewById(R.id.pager_tab_strip);
mViewPager.setCurrentItem(paginaCentrale);
modifica=(ImageView)findViewById(R.id.modifica);
modifica.setOnClickListener(this);
*mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
mCurrentFragment = pagerAdapter.getItem(position);
}*
});
#Override
public void onClick(View arg0) {
// TODO onClick
switch (arg0.getId()){
case R.id.modifica:
*mCurrentFragment.caricaLista();*
break;
}
}
}
Related
I have an Activity with ViewPager which manage 2 Fragments using FragmentStatePagerAdapter,
The fragments have ListViews, each of the ListView shows data and I am able to go from Fragment_A to Fragment_B by swipe or item tapping on the ListView of Fragment_A.
I am also able to update the underlying data source for Fragment_B based on the item selected in Fragment_A. But when I try to notifyDataSetChanged() on the DataAdapter of Fragment_B, I am getting NullPointerException .
I want to update the data in Fragment_B according to the item selected in Fragment_A.
Here is my code
public class MyActivity extends FragmentActivity implements AdapterView.OnItemClickListener{
ViewPager viewPager = null;
int mSelectedItemPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_fail_activity);
viewPager = (ViewPager) findViewById(R.id.fail_pager_VP);
viewPager.setAdapter(new pagerAdapter(getSupportFragmentManager()));
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mSelectedItemPosition = position;
viewPager.setCurrentItem(1);
FragmentStatePagerAdapter fspa = (FragmentStatePagerAdapter) viewPager.getAdapter();
Fragment_B item = (Fragment_B) fspa.getItem(1);
item.setData(position);
item.refresh();
}
}
class pagerAdapter extends FragmentStatePagerAdapter {
public pagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new Fragment_A();
} else if (position == 1) {
fragment = new Fragment_B();
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
String title = "";
if (position == 0) {
return "a_title";
}else if (position == 1) {
return "b_title";
}
}
}
public class Fragment_A extends android.support.v4.app.Fragment {
private ListView frag_a_listView;
DataAdapter dataAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ListView frag_a_listView = (ListView) getActivity().findViewById(R.id.frag_a_LV);
frag_a_listView.setOnItemClickListener((AdapterView.OnItemClickListener) getActivity());
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_fail_main, container, false);
frag_a_listView = (ListView) layout.findViewById(R.id.frag_a_LV);
dataAdapter = new DataAdapter(getActivity(),
R.layout.data_row,
R.id.data_label_TV,
getFrag_aData());
frag_a_listView.setAdapter(dataAdapter);
return layout;
}
private List<String> getFrag_aData() {
...
return someData;
}
}
public class Fragment_B extends android.support.v4.app.Fragment {
ListView frag_b_listView;
List<String> mData;
DataAdapter dataAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ListView frag_b_listView = (ListView) getActivity().findViewById(R.id.frag_b_LV);
frag_b_listView.setOnItemClickListener((AdapterView.OnItemClickListener) getActivity());
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_frag_b, container, false);
frag_b_listView = (ListView) layout.findViewById(R.id.frag_b_LV);
setData(0);
dataAdapter = new DataAdapter(getActivity(),
R.layout.data_row,
R.id.data_label_TV,
mData);
frag_b_listView.setAdapter(dataAdapter);
return layout;
}
public void setData(int position) {
...
mData = some List<String>;
}
public void refresh() {
dataAdapter.notifyDataSetChanged(); <------- this crashes the app
}
}
public class DataAdapter extends ArrayAdapter {
public DataAdapter(Context context, int resource, int textViewResourceId, List objects) {
super(context, resource, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = super.getView(position, convertView, parent);
return convertView;
}
}
here is the crash log
06-25 16:51:46.813 21537-21537/au.myCity.eight E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: au.myCity.eight, PID: 21537
java.lang.NullPointerException: Attempt to invoke virtual method 'void au.myCity.eight.dataAdapter.notifyDataSetChanged()' on a null object reference
at au.myCity.eight.fragments.Fragment_B.refresh(Fragment_B.java:56)
at au.myCity.eight.MyActivity.onItemClick(MyActivity.java:37)
at android.widget.AdapterView.performItemClick(AdapterView.java:305)
at android.widget.AbsListView.performItemClick(AbsListView.java:1146)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3053)
at android.widget.AbsListView$3.run(AbsListView.java:3860)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
After few tries with Log.d and checking some variable references.
The problem was the reference to Fragment_B changed by the time I called dataAdapter.notifyDataSetChanged(), to fix this I used the solution suggested in SO here, thanks to the "Streets Of Boston".
Summery, In the PagerAdapter:
Save a reference to initialized fragments in a SparseArray, use getRegisteredFragment in
onItemClick instead of getItem in MyActivity.
Override instantiateItem and destroyItem as suggested in the link.
A want to make my Widget dragable..
A use GWT and d&d. It's my code, but it isn't work..
#SuppressWarnings("deprecation")
public class StickWidget extends Composite implements SourcesMouseEvents {
private static StickWidgetUiBinder uiBinder = GWT
.create(StickWidgetUiBinder.class);
#UiField Label title;
#UiField HTML content;
interface StickWidgetUiBinder extends UiBinder<Widget, StickWidget> {
}
public StickWidget(String title, String content, String width, String height) {
super();
initWidget(uiBinder.createAndBindUi(this));
this.content.setText(content);
this.title.setText(title);
this.setWidth(width);
this.setHeight(height);
}
public StickWidget(String title, String content) {
initWidget(uiBinder.createAndBindUi(this));
this.content.setText(content);
this.title.setText(title);
}
#Override
public void addMouseListener(MouseListener listener) {
// TODO Auto-generated method stub
}
#Override
public void removeMouseListener(MouseListener listener) {
// TODO Auto-generated method stub
}
}
and fragment of my EntryPoint:
StickWidget a = new StickWidget("gg", "gg", "20px", "200px");
DropTargetStick dropT = new DropTargetStick(new Label("fdgf"));
PickupDragController dragController = new PickupDragController (RootPanel.get(), false);
dragController.registerDropController(dropT);
dragController.makeDraggable(a);
I think I done all steps which allow me to drag & drop My widget.. But it doesn't work..
I solve this problem. You must implement HasAllMouseHandlers and HasClickHandlers. And in implementation give somelike this -
#Override
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
// TODO Auto-generated method stub
return addDomHandler(handler, MouseUpEvent.getType());
}
I have followed the GettingStarted on the GWTP tutorial
http://code.google.com/p/gwt-platform/wiki/GettingStarted
but unfortunately handlers not working, getUiHandlers() return null and exception stacktrace is same as in:
How to use UiHandlers of GWT Platform?
.
View Class
public class AView extends ViewWithUiHandlers<AUiHandlers> implements APresenter.Display {
#UiTemplate("AView.ui.xml")
interface AViewUiBinder extends UiBinder<Widget, AView> {}
private static AViewUiBinder uiBinder = GWT.create(AViewUiBinder.class);
#UiField Button saveBtn;
#UiField Button cancelBtn;
#UiField DivElement errorDiv;
private Widget widget;
#Inject
public AssetView() {
widget = uiBinder.createAndBindUi(this);
}
public Widget asWidget() {
return widget;
}
// Implementation: Presenter's Display methods
public void setErrorDivText(String msg) {
errorDiv.getStyle().setDisplay(Display.BLOCK);
errorDiv.setInnerText(msg);
}
// Handlers
#UiHandler("saveBtn")
void onSaveButtonClick(ClickEvent event) {
if(getUiHandlers() != null) {
getUiHandlers().onSaveButtonClick();
}
}
#UiHandler("cancelBtn")
void onCancelButtonClick(ClickEvent event) {
if(getUiHandlers() != null) {
getUiHandlers().onCancelButtonClick();
}
}
}
Handler Interface
public interface AUiHandlers extends UiHandlers {
void onSaveButtonClick();
void onCancelButtonClick();
}
Presenter
public class APresenter extends Presenter<APresenter.Display, APresenter.AssetProxy> implements AUiHandlers {
public interface Display extends View, HasUiHandlers<AUiHandlers> {
public void setErrorDivText(String msg);
}
#ProxyStandard
#NameToken(NameTokens.ASSET)
public interface AssetProxy extends ProxyPlace<AssetPresenter> {}
#Inject
public AssetPresenter(EventBus eventBus, Display view, AssetProxy proxy) {
super(eventBus, view, proxy);
getView().setUiHandlers(this);
}
#Override
protected void onBind() {
super.onBind();
}
#Override
protected void revealInParent() {
RevealRootContentEvent.fire( this, this );
}
public void onSaveButtonClick() {
getView().setErrorDivText("Save clicked.");
}
public void onCancelButtonClick() {
getView().setErrorDivText("Cancel clicked.");
}
}
Unable to understand where i am making mistake, implementation regarding UiHandlers is same as told in the above mentioned tutorial's link.
UiHandlers is not generic; it cannot be parameterized with arguments
As I see your handler interface, you have passed AUiHandlers type. I don't understand the package structure of UiHandlers . it should be com.gwtplatform.mvp.client.UiHandlers.
Please check import of it.
Update:
Remove private static AViewUiBinder uiBinder = GWT.create(AViewUiBinder.class);
and Pass as constructor argument
#Inject
public AssetView(AViewUiBinder uiBinder) {
widget = uiBinder.createAndBindUi(this);
}
I trying to pass a parameter in the placerequest to a presenter that will be a popup, but, the i receive empty parameters in the popup presenter.. am i forgot anything?
AddProjetoPresenter
public class AddProjetoPresenter extends Presenter<AddProjetoPresenter.AddProjetoView, AddProjetoPresenter.AddProjetoProxy>
{
#ProxyCodeSplit
#NameToken(NameTokens.addproj)
public interface AddProjetoProxy extends ProxyPlace<AddProjetoPresenter>
{
}
public interface AddProjetoView extends View
{
HasValue<String> getNome();
HasValue<Date> getDtInicio();
HasValue<Date> getDtFim();
HasClickHandlers getAddRequisitos();
HasClickHandlers getAddStakeholders();
HasClickHandlers getBtCancelar();
HasClickHandlers getBtSalvar();
}
private final DispatchAsync dispatch;
private final PlaceManager placeManager;
private Projeto projeto;
#Inject
public AddProjetoPresenter(final EventBus eventBus, final AddProjetoView view, final AddProjetoProxy proxy, final DispatchAsync dispatch,
final PlaceManager placeManager)
{
super(eventBus, view, proxy);
this.dispatch = dispatch;
this.placeManager = placeManager;
}
#Override
protected void revealInParent()
{
RevealContentEvent.fire(this, MainPresenter.TYPE_SetMainContent, this);
}
#Override
protected void onBind()
{
super.onBind();
getView().getBtSalvar().addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
}
});
getView().getAddRequisitos().addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
PlaceRequest pr = new PlaceRequest(NameTokens.addreq);
pr.with("oi", "oiiiii"); // HERE
placeManager.revealPlace(pr, false);
}
});
}
}
AddRequisitoPresenter
public class AddRequisitoPresenter extends Presenter<AddRequisitoPresenter.AddRequisitoView, AddRequisitoPresenter.AddRequisitoProxy>
{
#ProxyCodeSplit
#NameToken(NameTokens.addreq)
public interface AddRequisitoProxy extends ProxyPlace<AddRequisitoPresenter>
{
}
public interface AddRequisitoView extends PopupView
{
DialogBox getDialog();
}
private final DispatchAsync dispatcher;
private Projeto projeto;
#Inject
public AddRequisitoPresenter(final EventBus eventBus, final AddRequisitoView view, final AddRequisitoProxy proxy, final DispatchAsync dispatcher)
{
super(eventBus, view, proxy);
this.dispatcher = dispatcher;
}
#Override
public void prepareFromRequest(PlaceRequest request)
{
super.prepareFromRequest(request);
getView().getDialog().setText(request.getParameterNames().size() + ""); //SIZE IS ZERO!!
}
#Override
protected void onBind()
{
super.onBind();
}
#Override
protected void revealInParent()
{
RevealRootPopupContentEvent.fire(this, this);
}
}
I think ai doing something wrong...
thanks in advance.
From what I understood in the wiki, a popup can't be a place, and it needs a parent presenter.
I see two obvious problems here :
Your second presenter (the popup) should implement PresenterWidget, not Presenter
You can't display a popup by calling placeManager.revealPlace(), because a popup is not a place. Instead, you have to apply one of the two methods explained in the wiki (addToPopupSlot() or RevealRootPopupContentEvent.fire(), both called from the parent).
I have a gwt VerticalPanel class that i need to handel KeyDown events for it.
the method i used to implement keyboard handler in my class is:
i add :
this.sinkEvents(Event.ONKEYDOWN);
to constructor
then i override method onBrowserEvent() to handle key down event.
#Override
public void onBrowserEvent(Event event) {
// TODO Auto-generated method stub
super.onBrowserEvent(event);
int type = DOM.eventGetType(event);
switch (type) {
case Event.ONKEYDOWN:
//call method to handle this keydown event
onKeyDownEvent(event);
break;
default:
return;
}
}
however this method doesn’t work for this VerticalPanel class.no KeyDown Event is fired when i press a key!
there are specific gwt widgets that support KeyDownHandler like Button etc..VerticalPanel is not one of them..so we need a work around to register a KeyDownHandler on a class extending VerticalPanel.
can you suggest an idea or hint?
thanks
You could create a Composite that wrappes a FocusPanel and a VerticalPanel. This way you can catch all key events provided the FocusPanel is focused. Simply delegate the needed methods to the panels:
public void onModuleLoad() {
ExtendedVerticalPanel panel = new ExtendedVerticalPanel();
panel.add(new Label("some content"));
panel.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
Window.alert("enter hit");
}
}
});
RootPanel.get().add(panel);
}
private class ExtendedVerticalPanel extends Composite implements HasWidgets, HasAllKeyHandlers {
private VerticalPanel fVerticalPanel;
private FocusPanel fFocusPanel;
public ExtendedVerticalPanel() {
fVerticalPanel = new VerticalPanel();
fFocusPanel = new FocusPanel();
fFocusPanel.setWidget(fVerticalPanel);
initWidget(fFocusPanel);
}
#Override
public void add(Widget w) {
fVerticalPanel.add(w);
}
#Override
public void clear() {
fVerticalPanel.clear();
}
#Override
public Iterator<Widget> iterator() {
return fVerticalPanel.iterator();
}
#Override
public boolean remove(Widget w) {
return fVerticalPanel.remove(w);
}
#Override
public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
return fFocusPanel.addKeyUpHandler(handler);
}
#Override
public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
return fFocusPanel.addKeyDownHandler(handler);
}
#Override
public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
return fFocusPanel.addKeyPressHandler(handler);
}
}
UPDATE
Your question on how to prevent the browser from scrolling when the arrow keys are pressed. Here a small example that works for me:
public void onModuleLoad() {
ExtendedVerticalPanel panel = new ExtendedVerticalPanel();
// make panel reeeeaally big
panel.setHeight("3000px");
panel.add(new TextBox());
panel.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_DOWN) {
Window.alert("down hit");
event.preventDefault();
}
}
});
RootPanel.get().add(panel);
}
Add the handlers you need and call preventDefault() on the events the browser must not take care of.