Reputation: 241
I am developing an app where the user can type in stuff in edittexts and get to the next view by swiping the screen. The swiping-stuff is handled by a viewpager.
What I want to do is the following:
The user should only be able to swipe when all edittexts are filled. Currently all my edittexts have a TextWatcher whichs sets a boolean value to "true" once every field is filled. When it is true, I want to enable the viewpager, when it isn't, I want to disable it.
I'm using a CustomViewPager with three Fragments. I post my CustomViewPager code:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Toast;
public class CustomViewPager extends ViewPager {
private boolean isPagingEnabled;
public Context context;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.isPagingEnabled = true;
this.context = context;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isPagingEnabled) {
return super.onTouchEvent(event);
}
Toast.makeText(context, "Please fill in the details, then swipe !",
Toast.LENGTH_LONG).show();
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (isPagingEnabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}
public void setPagingEnabled(boolean b) {
isPagingEnabled = b;
}
}
PageViewActivity.java
public class PageViewActivity extends FragmentActivity {
MyPageAdapter pageAdapter;
int pageId=0;
public static CustomViewPager pager;
PageListener pageListener;
int currentPage=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
pager =(CustomViewPager)findViewById(R.id.viewpager);
pager.setAdapter(pageAdapter);
pager.setPagingEnabled(false);
pageListener = new PageListener();
pager.setOnPageChangeListener(pageListener);
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(MyFragmentA.newInstance("Fragment 1"));
fList.add(MyFragmentB.newInstance("Fragment 2"));
fList.add(MyFragmentC.newInstance("Fragment 3"));
return fList;
}
public void next(View v){
if(pageId<=2)
{
pager.setCurrentItem(pageId);
}
pageId++;
}
private class PageListener extends SimpleOnPageChangeListener{
public void onPageSelected(int position) {
Log.i("test", "onPageSelected " + position);
currentPage = position;
}
//Called when the scroll state changes.
public void onPageScrollStateChanged(int state)
{
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
Log.i("test", "onPageScrolled " + position);
currentPage = position;
}
}
}
My Page Adapter is this:
import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.widget.Toast;
class MyPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
Finally I post one of my Fragments with the only relevant code:
public class MyFragmentA extends Fragment {
EditText editname;
public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE";
public static final MyFragmentA newInstance(String message)
{
MyFragmentA f = new MyFragmentA();
Bundle bdl = new Bundle(1);
bdl.putString(EXTRA_MESSAGE, message);
f.setArguments(bdl);
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
editname = (EditText)myFragmentView.findViewById(R.id.name_input);
editname.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(editname.getText().toString().trim().length() == 0) {
// Can I set here isPagingEnabled = false??
Toast.makeText(getActivity(), "SwipeFlag false!", Toast.LENGTH_SHORT).show();
} else if(editname.getText().toString().trim().length() > 0) {
// Can I set here isPagingEnabled = true??
Toast.makeText(getActivity(), "SwipeFlag true!", Toast.LENGTH_SHORT).show();
}
}
});
return myFragmentView;
}
}
I know that the keypoint to block page swipe is to set the flag "isPagingEnabled" to false, but I can't understand what is the best way to set it from a Fragment at runtime.
Upvotes: 1
Views: 2863
Reputation: 241
Ok, I finally found a solution and I post it here.. The best way to block page swipe is to control if edit text is filled inside onPageScrolled in PageViewActivity.java (my MainActivity..):
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.i("test", "onPageScrolled - position = " + position);
currentPage = position;
txt1 = (EditText) findViewById(R.id.name_input);
if(position == 0) {
if(txt1.getText().toString().trim().length() == 0) {
pager.setCurrentItem(0);
} else if(txt1.getText().toString().trim().length() > 0) {
// DO NOTHING
}
}
}
In that way page swipe is not allowed until the edittext field of your fragment is filled.
Another wise way to block page swipe, but ONLY in the right direction is to modify onPageSelected in this way:
boolean inibitFlag = false;
int maxAllowedPage = 1; // .. or you can set this value in your fragment..
public void onPageSelected(int position) {
Log.i("test", "onPageSelected " + position);
if(inibitFlag)
return;
if(position > maxAllowedPage) {
inibitFlag = true;
pager.setCurrentItem(currentPage);
inibitFlag = false;
} else {
currentPage = position;
}
}
Hope this helps someone!!
Upvotes: 3