I have ViewPager. Every ViewPager's page is customView. In custom view class in addOnPageChangeListener(new ViewPager.OnPageChangeListener() method I get null. I can't understand why, because in other method with viewPager - setOnClickListener(new OnClickListener() there are no null. This method works.
my custom view:
public class CustomView extends LinearLayout {
private LayoutInflater mInflater;
private Button button;
private ViewPager viewPager;
public void setPager(ViewPager viewPager) {
this.viewPager = viewPager;
}
public CustomView(#NonNull Context context) {
super(context);
}
public CustomView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
mInflater = LayoutInflater.from(context);
View v = mInflater.inflate(R.layout.custom_view, this, true);
button = v.findViewById(R.id.nextButton);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
and activity class:
public class Activity extends AppCompatActivity {
private ViewPager viewPager;
private CustomPagerAdapter customPagerAdapter;
private CustomView customView;
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customPagerAdapter = new CustomPagerAdapter(this);
viewPager = findViewById(R.id.viewPager);
customView = findViewById(R.id.customView);
viewPager.setAdapter(customPagerAdapter);
customView.setPager(viewPager);
}
}
and I get error:
E/AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.addOnPageChangeListener(androidx.viewpager.widget.ViewPager$OnPageChangeListener)' on a null object reference
at CustomView.<init>(line : viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener())
You are calling the addOnPageChangeListener in constructor of the CustomView, and the viewpager is not set in your view yet. Try to call addOnPageChangeListener in your setPager method.
public class CustomView extends LinearLayout {
private LayoutInflater mInflater;
private Button button;
private ViewPager viewPager;
public void setPager(ViewPager viewPager) {
this.viewPager = viewPager;
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
public CustomView(#NonNull Context context) {
super(context);
}
public CustomView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
mInflater = LayoutInflater.from(context);
View v = mInflater.inflate(R.layout.custom_view, this, true);
button = v.findViewById(R.id.nextButton);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
}
});
}
Related
I have viewPager with 2 views. I need to get the second view by click and by flip. It works. But when I an in the second view I have to have button animation. This button is my customView. This animation doesn't work. And I don't know why. onPageSelected(int position) method works, because I get log.
my customView class:
public class CustomView extends LinearLayout {
private LayoutInflater mInflater;
private Button button;
private ViewPager viewPager;
private float buttonWidth;
public void setPager(ViewPager viewPager) {
this.viewPager = viewPager;
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
setClick();
}
#Override
public void onPageSelected(int position) {
ViewTreeObserver vto = button.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
buttonWidth = button.getWidth();
}
});
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
boolean isDisplayPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
float middleScreen = isDisplayPortrait ? metrics.widthPixels / 2 : metrics.heightPixels / 2;
float movingDistanceForButton = middleScreen - buttonWidth / 2;
final TranslateAnimation animation = new TranslateAnimation(0, movingDistanceForButton, 0, 0);
animation.setDuration(3000);
animation.setFillAfter(true);
if (position == 1) {
button.setAnimation(animation);
Log.e("position1", "pos1");
} else {
button.getAnimation().cancel();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
public CustomView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
mInflater = LayoutInflater.from(context);
View v = mInflater.inflate(R.layout.custom_view, this, true);
button = v.findViewById(R.id.nextBotton);
}
public void setClick() {
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
}
});
}
and my activity class:
public class Activity extends AppCompatActivity {
private ViewPager viewPager;
private PagerAdapter customPagerAdapter;
private CustomView customView;
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customPagerAdapter = new PagerAdapter(this);
viewPager = findViewById(R.id.viewPager);
customView = findViewById(R.id.myCustomView);
viewPager.setAdapter(customPagerAdapter);
customView.setPager(viewPager);
}
I have below 2 Java class files (Main and Adapter).I want to stop audio when back button is pressed but my tries are exhausted.When the back button is pressed, it should go to a 3rd activity.So, I'm looking for help.Main class
public class myClass extends AppCompatActivity {
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
viewPager = (ViewPager) findViewById(R.id.pagerOne);
PagerAdapter viewPagerAdapter = new PagerAdapter(this);
viewPager.setAdapter(viewPagerAdapter);}
}
Adapter class
public class MyPagerAdapter extends PagerAdapter {
Context context;
LayoutInflater inflater;
MediaPlayer mp;
public int[] images = { R.drawable.img1,R.drawable.img2 };
public String[] title = { "Image1","Image2" };
public PagerAdapter(Context context) { this.context = context; }
#Override
public int getCount() { return title.length; }
#Override
public boolean isViewFromObject(View view, Object object) { return (view == object); }
#Override
public Object instantiateItem(ViewGroup container, final int position) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.activity_custlayout,container,false);
ImageView slide = view.findViewById(R.id.myView);
TextView text= view.findViewById(R.id.txt);
slide.setImageResource(images[position]);
text.setText(title[position]);
releaseMediaPlayer();
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { releaseMediaPlayer();
if (position == 0){ setupMediaPlayer(R.raw.lion); }
else if (position == 1){ setupMediaPlayer(R.raw.tiger); }
else { setupMediaPlayer(R.raw.tortoise);}
}
}); container.addView(view); return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) { releaseMediaPlayer(); container.removeView((ConstraintLayout)object); }
public void setupMediaPlayer(int resource) { mp = MediaPlayer.create(context, resource); mp.start(); }
public void releaseMediaPlayer() { if (mp != null) { mp.stop(); mp.release(); mp = null; } }
}
Unsuccessful tryI tried to release the audio from main class like below but it didn't work.
PagerAdapter pagerAdapter = new PagerAdapter(this);pagerAdapter.releaseMediaPlayer();
You should override onBackPressed() callback in your Main class and also make sure that you are using the same instance of PagerAdapter.
This is how you should do it
public class myClass extends AppCompatActivity {
ViewPager viewPager;
MyPagerAdapter myPagerAdapter; // Move the variable here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
viewPager = (ViewPager) findViewById(R.id.pagerOne);
myPagerAdapter = new MyPagerAdapter(this); // Modify this line
viewPager.setAdapter(viewPagerAdapter);}
}
#Override
protected void onBackPressed() {
myPagerAdapter.releaseMediaPlayer();
// Go to 3rd Activity
}
Anyway, you are calling PagerAdapter directly while actually you should use your own MyPagerAdapter.
Am using a ViewPager with adapter to show some pictures (as a gallery) and I need to return the name of the picture when the user click above
my problem that I can not implement onclick from the adapter because I can't return the result to the calling activity, and when I implement the viewAdapter.addOnPageChangeListener I have to wait until the page is changed so if the user clicks on the first pic it well not work
here is my code:
for(int i=0;i<images.length;i++)
imagesArray.add(images[i]);
MyAdapter myAdapter = new MyAdapter(MyImagePicker.this,imagesArray);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(myAdapter);
//CircleIndicator indicator = (CircleIndicator) findViewById(R.id.indicator);
//indicator.setViewPager(mPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(mPager, true);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Toast.makeText(getApplicationContext()," pos : "+position,Toast.LENGTH_LONG).show();
// return result //
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
class MyAdapter extends PagerAdapter {
private ArrayList<Integer> images;
private LayoutInflater inflater;
private Context context;
public MyAdapter(Context context, ArrayList<Integer> images) {
this.context = context;
this.images=images;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return images.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View myImageLayout = inflater.inflate(R.layout.slider, view, false);
final ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.image);
myImage.setImageResource(images.get(position));
myImage.setTag(position+1);
myImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context," pos : "+view.getTag(),Toast.LENGTH_LONG).show();
}
});
view.addView(myImageLayout, 0);
return myImageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
}
There are a few approaches you could take:
1) Create a callback interface. In your activity implement the interface (create a listener) and pass it into the adapter's constructor, when the user clicks on an image, pass the image name back to the activity using the callback (mlistener.onImageChosen(view.getTag()).
public interface ImageChosenListener
{
void onImageChosen(String image);
}
2) Use a broadcast from the adapter and have a broadcast receiver in your activity.
try this.
mPager.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(mPager.getCurrentItem()){
case 0: // its position 0
//somthing
break;
.
.
.
}
});
Thanks jt-gilkeson,
I think using a callBack interface is the perfect and the easiest solution :
Here is my answer :
// Create a callBack interface
public interface CallBack {
void callBack(String pos);
}
// The activity hosting my picture gallery
public class MyImagePicker extends Activity implements CallBack {
private static ViewPager mPager;
private static final Integer[] images= {R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4};
private ArrayList<Integer> imagesArray = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.galery_image_chooser);
init();
}
private void init() {
for(int i=0;i<images.length;i++)
imagesArray.add(images[i]);
MyAdapter myAdapter = new MyAdapter(MyImagePicker.this,imagesArray,this);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(myAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(mPager, true);
}
// Implement the call back function
public void callBack(String pos){
//return back result
Intent intent=new Intent();
intent.putExtra("imgName",pos);
setResult(2,intent);
finish();//finishing activity
}
}
i have 2 fragment in my tab layout, i manage to disable the swiping function between tab layout by button click. How to implement the disable function in my onclick button. thanks for advance
MainActivity
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener{
private TabLayout tabLayout;
private ViewPager viewPager;
int ans =2;
------FCViewPager disable;------
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
BasePagerAdapter adapter = new BasePagerAdapter(getSupportFragmentManager());
Tab1 tab1 = new Tab1();
Tab2 tab2 = new Tab2();
adapter.addFragment(tab1, "1");
adapter.addFragment(tab2, "2");
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(adapter);
tabLayout.setOnTabSelectedListener(this);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setupWithViewPager(viewPager);
}
----- public void testing( View view) {
disable.setEnableSwipe(false);
}---------
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
public class BasePagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public BasePagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public void removeFragment(int position) {
mFragmentTitleList.remove(position);
mFragmentList.remove(position);
notifyDataSetChanged();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Tab1
public class Tab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View h = inflater.inflate(R.layout.tab1, container, false);
return h;
}
}
Tab2
public class Tab2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View h = inflater.inflate(R.layout.tab2, container, false);
return h;
}
You can disable swipe feature in your ViewPager. Create custom ViewPager as follow.
public class FCViewPager extends ViewPager {
private boolean enableSwipe;
public FCViewPager(Context context) {
super(context);
init();
}
public FCViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
enableSwipe = true;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return enableSwipe && super.onInterceptTouchEvent(event);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return enableSwipe && super.onTouchEvent(event);
}
public void setEnableSwipe(boolean enableSwipe) {
this.enableSwipe = enableSwipe;
}
}
In your MainActivity
//R.id.pager has to be FCViewPager not default ViewPager
viewPager = (FCViewPager) findViewById(R.id.pager);
Your button onClick function
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pager.setEnableSwipe(false);
}
});
User scroll disable viewpager for disabling and enabling scrolling by default and programmatically
public class ScrollDisabledViewpager extends ViewPager {
private boolean isPagingEnabled = false;
public ScrollDisabledViewpager(Context context) {
super(context);
}
public ScrollDisabledViewpager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onTouchEvent(event);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onInterceptTouchEvent(event);
}
public void setPagingEnabled(boolean b) {
this.isPagingEnabled = b;
}
}
Button onClick event you can set this true/false to enable/ disable scrolling
viewPager.setPagingEnabled(true/ false);
I am using view-pager with fragment in my application. i want to add and remove any key/value from hash-map but it gives me null pointer exception. there are 5 elements in hash-map if i remove last key from map then it works fine. How to solve it.
Below is my problem code :
public class MainActivity extends AppCompatActivity {
ViewPager viewPager;
public PagerAdapter adapter1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager1);
final HashMap<String,Integer> sliderDataList = new HashMap<String,Integer>();
sliderDataList.put("0",R.drawable.first);
sliderDataList.put("1",R.drawable.second);
sliderDataList.put("2",R.drawable.three);
sliderDataList.put("3",R.drawable.four);
sliderDataList.put("4",R.drawable.xiaomi);
adapter1 = new PagerAdapter(getSupportFragmentManager(), sliderDataList, MainActivity.this);
viewPager.setAdapter(adapter1);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
remove("3");
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void remove(String s){
adapter1.remove(s);
}
public class PagerAdapter extends FragmentStatePagerAdapter {
private HashMap<String, Integer> hMap;
private final Context context;
public PagerAdapter(FragmentManager fm, HashMap<String,Integer> hMap, Context context) {
super(fm);
this.hMap=hMap;
this.context=context;
}
#Override
public int getItemPosition (Object object)
{
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
return new SliderFragment(hMap,context,position);
}
#Override
public int getCount() {
return hMap.size();
}
public void remove(String s){
hMap.remove(s);
adapter1.notifyDataSetChanged();
}
}
#SuppressLint("ValidFragment")
public static class SliderFragment extends Fragment {
private HashMap<String, Integer> urls;
private int imageResourceId;
ImageView imageView;
private Context ctx;
public SliderFragment(HashMap<String,Integer> urls, Context c, int pos) {
this.urls = urls;
this.imageResourceId = pos;
this.ctx = c;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_main, container, false);
imageView = (ImageView) view.findViewById(R.id.img);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(urls.get(imageResourceId +""));
return view;
}
}
}
public void remove(String s){
if(sliderDataList.containskey("3"))
{
containskey.remove("3");
adapter1.notifydataSetChanged();
}
}
Try this:
Iterator<Map.Entry<String,String>> iter = TestMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,String> entry = iter.next();
if("Sample".equalsIgnoreCase(entry.getValue())){
iter.remove();
}
}
if you just want to remove the null pointer exception, then add this:
if (urls.get(imageResourceId + "") != null)
imageView.setImageResource(urls.get(imageResourceId + ""));