How to assign buttons at different points of 70 images separately?

My problem:

I have 70 images, and on each image I want to put a transparent button so that when the user clicks on it, it reproduces a short sound relative to the place in the image. Images are displayed in the ViewPager .

My decision:

Now I mean that I can create 70 fragments, each of which contains a corresponding image as a background, and I can easily assign a button to each place and assign actions to those buttons that will play their corresponding sound.

But

this doesn't seem like a good approach involving 70 fragments in one application.

So how can I achieve this, and what will be the best approach that I can use?

+5
source share
5 answers

We can just have one fragment and create an ArrayList of Map (Button, RelatedAudioFile) data structure to store the buttons and their associated audio files. The ArrayList index represents the page number.

Example: Now suppose we have 3 views. Since most PagerAdapter indexes start with "0", let's say that Page-0 contains 3 buttons, Page-1 contains 1 button, Page-2 contains 2 buttons.

Pseudocode:

 class PagerHolder extends Fragment { //buttons list - here, arrayList index represents page number //and at each index we have map of buttons (buttons in each of these pages) and the related audio files private ArrayList<Map<Button, RelatedAudioFile>> pageButtonsList = new ArrayList<>(); //pager view private ViewPager viewPager; //pager adapter private PagerAdapter pagerAdapter; //current page number -- page in which we are in right now private int currentpageNumber = 0; //buttonListener -- one button listener for all the buttons in all the pages. private View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View buttonView) { //here you can play the audio. //buttonView -- is the same button-object that was pressed. ((RelatedAudioFile)pageButtonsList.get(currentpageNumber).get(buttonView)).play(); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); pagerAdapter = new PagerAdapter(getChildFragmentManager()); //add buttons to the list //page 0 buttons HashMap<Button, RelatedAudioFile> page0Buttons = new HashMap<>(); page0Buttons.put(new Button(context), new RelatedAudioFile()); page0Buttons.put(new Button(context), new RelatedAudioFile()); page0Buttons.put(new Button(context), new RelatedAudioFile()); pageButtonsList.add(page0Buttons) //Adding page 1 buttons: HashMap<Button, RelatedAudioFile> page1Buttons = new HashMap<>(); page1Buttons.put(new Button(context), new RelatedAudioFile()); pageButtonsList.add(page1Buttons); //Adding page 2 buttons: HashMap<Button, RelatedAudioFile> page2Buttons = new HashMap<>(); page2Buttons.put(new Button(context), new RelatedAudioFile()); page2Buttons.put(new Button(context), new RelatedAudioFile()); pageButtonsList.add(page2Buttons); for(Map<Button, RelatedAudioFile> pageButtons :pageButtonsList) { for(Button button : pageButtons.keySet()) { button.setOnClickListener(listener); } } } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_editor_pager, container, false); viewPager = (ViewPager) v.findViewById(R.id.view_pager); viewPager.setAdapter(pagerAdapter); return v; } private class PagerAdapter extends FragmentPagerAdapter { private ButtonFragment buttonFragment; private PagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int pageNumber) { currentpageNumber = pageNumber; //pass the buttons to the fragment so that it can add these buttons to the screen buttonFragment = ButtonFragment.newInstance(pageButtonsList.get(pageNumber).keySet()); //to add buttons on screen programatically at certain position you can refer here: // http://stackoverflow.com/questions/3441475/android-change-absolute-position-of-a-view-programmatically } //number of pages @Override public int getCount() { return 70; } } 
+1
source

You do not need to create 70 fragments. Instead, you can simply use a single ImageView as follows:

 final List<Integer> list = new ArrayList<>(); list.add(R.drawable.img_0); list.add(R.drawable.img_1); ... list.add(R.drawable.img_69); ImageView img = (ImageView)findViewById(R.id.imageView); img.setBackgroundResource(list.get(yourIndex)); img.setOnClickListener(new OnClickListener());//plays the audio 
0
source

You do not need to declare 70 fragments, just create one fragment and declare global arrays of images and sound on this fragment. Now, when you redirect the fragment here, just pass in an argument an integer variable. Now you can display the image from the array using this integer variable, and when you click the button, you can play the sound from the sound array using the same integer number.

0
source

Use this custom view player

 import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; /** * Created by Jinesh on 06-01-2016. */ public class CustomViewPager extends ViewPager { private boolean enabled; public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); this.enabled = true; } @Override public boolean onTouchEvent(MotionEvent event) { if (this.enabled) { return super.onTouchEvent(event); } return false; } @Override public boolean onInterceptTouchEvent(MotionEvent event) { /* if (this.enabled) { return super.onInterceptTouchEvent(event); } */ return false; } public void setPagingEnabled(boolean enabled) { this.enabled = enabled; } } 

Add this tag to your xml

 <Your_package_name.CustomViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/vP_asq_Pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> 

Then add the PagerAdapter

 public class HomeAdapter extends PagerAdapter { public HomeAdapter(){ } @Override public int getCount() { return mItemList.size(); } @Override public Object instantiateItem(ViewGroup container, int position) { LayoutInflater inflater = (LayoutInflater) container.getContext().getSystemService(LAYOUT_INFLATER_SERVICE); v = inflater.inflate(R.layout.adapter_surveyquestion_view, null); /*do your operations on your views here store the 70 images in arraylist and return the size of the arraylist in getCount() method of the adapter.show different images each time in getView based on the position variable.*/ (container).addView(v); return v; } @Override public boolean isViewFromObject (View view, Object object){ return view == ((View) object); } @Override public void restoreState (Parcelable arg0, ClassLoader arg1){ } @Override public Parcelable saveState () { return null; } @Override public void destroyItem (ViewGroup container,int position, Object object){ container.removeView((View) object); } } 
0
source

So I would do. Please note that this is a single-class solution, e.g. assignment, you can separate classes

  • It will only contain 5 fragments at a time
  • The screen is divided into 4 buttons, you can set the alpha value of the buttons and size according to the need at the moment, I kept it half transparent, for example.
  • I use Glide to upload images to avoid OOM problems due to image loading.

What does it look like

enter image description here

Decision: -

 package com.example.sample; import java.util.ArrayList; import com.bumptech.glide.Glide; import android.content.Context; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.FrameLayout; import android.widget.ImageView; public class MainActivity extends FragmentActivity { private static ArrayList<Integer> imageList = new ArrayList<Integer>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Load image data for (int i = 0; i < 70; i++) { imageList.add(R.drawable.ic_launcher); } if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); ViewPager viewPager = (ViewPager) rootView .findViewById(R.id.image_pager); // Limit number of pages that should be retained to either // side of the current page viewPager.setOffscreenPageLimit(2); viewPager.setAdapter(new SongDetailAdapter(getActivity())); return rootView; } } public static class SongDetailAdapter extends PagerAdapter { Context mContext; LayoutInflater mLayoutInflater; public SongDetailAdapter(Context context) { mContext = context; mLayoutInflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return imageList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == ((FrameLayout) object); } @Override public Object instantiateItem(ViewGroup container, final int position) { View itemView = mLayoutInflater.inflate( R.layout.image_place_holder, container, false); ImageView imageView = (ImageView) itemView .findViewById(R.id.background); itemView.findViewById(R.id.button1).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { playSound(1); } }); itemView.findViewById(R.id.button2).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { playSound(2); } }); itemView.findViewById(R.id.button3).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { playSound(3); } }); itemView.findViewById(R.id.button4).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { playSound(4); } }); Glide.with(mContext).load("").placeholder(imageList.get(position)) .crossFade(300).into(imageView); container.addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((FrameLayout) object); } @Override public Object instantiateItem(View arg0, int arg1) { // TODO Auto-generated method stub return null; } @Override public Parcelable saveState() { // TODO Auto-generated method stub return null; } /* * Play sound */ private void playSound(int buttonNumber) { switch (buttonNumber) { case 1: // play sound for Button1 case 2: // play sound for Button2 case 3: // play sound for Button3 case 4: // play sound for Button4 default: // play sound for Button n // Playing default notification here for example Uri notification = RingtoneManager .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); Ringtone r = RingtoneManager .getRingtone(mContext, notification); r.play(); break; } } } } 

Layouts

The main activity_ activity_main.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.sample.MainActivity" tools:ignore="MergeRootFrame" /> 

The main fragment fragment_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.sample.MainActivity$PlaceholderFragment" > <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/image_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> 

Image holder with empty buttons imae_place_holder.xml

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/background" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:orientation="horizontal" > <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:alpha=".5" android:background="@android:color/white" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:alpha=".5" android:background="@android:color/holo_green_light" android:text="Button" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:orientation="horizontal" > <Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:alpha=".5" android:background="@android:color/holo_blue_light" android:text="Button" /> <Button android:id="@+id/button4" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:alpha=".5" android:background="@android:color/holo_red_light" android:text="Button" /> </LinearLayout> </LinearLayout> </FrameLayout> 
0
source

All Articles