如何分别在 70 张图像的不同位置分配按钮?

Posted

技术标签:

【中文标题】如何分别在 70 张图像的不同位置分配按钮?【英文标题】:How to assign buttons on different spots of 70 images separately? 【发布时间】:2016-04-30 07:38:37 【问题描述】:

我的问题:

我有 70 张图片,我想在每张图片上放置透明按钮 这样当用户点击它时,它会播放一段简短的音频 关于图像上的位置。图片以ViewPager 显示。

我的解决方案:

现在我的想法是,我可以创建 70 个片段,每个片段都包含各自的图像作为背景,我可以轻松地在每个位置分配按钮,并将操作分配给将播放各自音频的按钮。

但是

这看起来不是在单个应用中包含 70 个片段的好方法。

那么我该如何实现这一点,我可以使用什么更好的方法?

【问题讨论】:

您可以在特定坐标处以编程方式添加按钮。 你是在本地播放音频文件吗? 是的,图像和音频都是本地原始文件 【参考方案1】:

我们可以只拥有一个片段并创建一个 Map(Button, RelatedAudioFile) 数据结构的 ArrayList,用于保存按钮和相关音频文件。 ArrayList 索引代表页码。

示例: 现在假设我们有 3 个 viewPages。由于大部分 PagerAdapter 索引从“0”开始,假设 Page-0 包含 3 个按钮,Page-1 包含 1 个按钮,Page-2 包含 2 个按钮。

伪代码:

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://***.com/questions/3441475/android-change-absolute-position-of-a-view-programmatically
    

    //number of pages
    @Override
    public int getCount() 
        return 70;
    

【讨论】:

【参考方案2】:

您不必创建 70 个片段。相反,您可以只使用一个 ImageView,如下所示:

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

【讨论】:

但我需要在每个图像的不同位置添加按钮,当用户单击该位置时,它会播放不同的短音频,每个位置都不同。 检查 yourIndex 后,您可以在 OnClickListener 中播放不同的音频【参考方案3】:

您不需要声明 70 个片段,只需创建一个片段并在该片段上声明图像和声音的全局数组。现在,当您在片段处重定向时,只需在参数中传递一个整数变量。因此,现在您可以使用该整数变量从数组中显示图像,并且在单击按钮时,您可以使用相同的整数从声音数组中播放音频。

【讨论】:

这些图像将在ViewPager 内,并且每张图像都有音频数量,5 - 10 可以在不同的坐标播放 好的,那么你需要实现 ViewPager 的方法来显示图像,然后 setTag(position) 到 ImageView,所以点击你可以通过 getTag() 获取位置并从该位置播放音频。此外,您需要在 viewPager 文件上声明声音数组以进行访问,或者您可以在主活动中将其声明为全局,然后您可以将其作为 MainActivity.sounds[position] 访问以播放声音。【参考方案4】:

使用此自定义视图寻呼机

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;
    

将此标签添加到您的 xml 中

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

然后扩展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);
        


    

【讨论】:

【参考方案5】:

我会这样做。请注意,这是一个单类解决方案,您可以将类分开

这将一次只保留 5 个片段 屏幕分为 4 个按钮,您可以根据需要设置按钮的 alpha 值和大小,目前我将其保持为半透明,例如 我正在使用Glide进行图片加载,以避免图片加载导致的OOM问题

是什么样子的

解决方案:-

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;
            

        

    

布局

主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_
    android:layout_
    tools:context="com.example.sample.MainActivity"
    tools:ignore="MergeRootFrame" />

主要片段布局fragment_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    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_
        android:layout_ />

</RelativeLayout>

带有虚拟按钮的图像占位符 imae_place_holder.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

    <ImageView
        android:id="@+id/background"
        android:layout_
        android:layout_ />

    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="vertical" >

        <LinearLayout
            android:layout_
            android:layout_
            android:layout_weight="1.0"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/button1"
                android:layout_
                android:layout_
                android:layout_weight="1.0"
                android:alpha=".5"
                android:background="@android:color/white"
                android:text="Button" />

            <Button
                android:id="@+id/button2"
                android:layout_
                android:layout_
                android:layout_weight="1.0"
                android:alpha=".5"
                android:background="@android:color/holo_green_light"
                android:text="Button" />
        </LinearLayout>

        <LinearLayout
            android:layout_
            android:layout_
            android:layout_weight="1.0"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/button3"
                android:layout_
                android:layout_
                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_
                android:layout_
                android:layout_weight="1.0"
                android:alpha=".5"
                android:background="@android:color/holo_red_light"
                android:text="Button" />
        </LinearLayout>
    </LinearLayout>

</FrameLayout>

【讨论】:

以上是关于如何分别在 70 张图像的不同位置分配按钮?的主要内容,如果未能解决你的问题,请参考以下文章

分别上传多个图像并使用不同的按钮

如何应用属性,对不同地区的按钮说“禁用”?

1 张图片 2 个链接

在静态背景图像上调整按钮大小和位置

单击下一步按钮如何更改图像

Java 图标图像最大文件大小