疯狂猜歌实现(4)—— 实现文字待选框与已选文字框布局

来源:互联网 发布:诗词 知乎 编辑:程序博客网 时间:2024/05/01 17:14

本节要实现的是文字待选框的布局,要实现的效果如下:

由于在Android现有控件中没有此类控件,则此处需要用到自定义控件。分析此文字待选框是一个GridView + 若干Button组合而成的,而每一个待选文字的Button并不是一个单纯的Button,它需要一些自己特有的属性,如记录该控件的index,是否可见visable,button显示的文字等,所以其实这个button也是一个自定义的控件。

首先我们先来实现这一个自定义的button,新建pakage, 定义一个类WordButton,并写好它需要的属性。

package com.crazy.guess.music.model;import android.widget.Button;/** * 按钮实体类 * Created by vic_ma on 15/9/8. */public class WordButton {    //按钮索引    public int mIndex;    //按钮文字    public String mWordText;    //是否可见    public boolean mVisable;    //按钮Button    public Button mButton;    public WordButton(){        this.mWordText = "";        this.mVisable = true;    }}

在这里我们也定义好,WordButton中Button的布局文件,如下word_button_item.xml

<span style="font-family: Arial, Helvetica, sans-serif;"><!-- 待选文字按钮布局   --></span>

<Button xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/item_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:gravity="center"    android:textColor="@color/black"    android:textSize="18sp"    android:background="@drawable/word_button_selector"></Button>
自定义按钮准备好以后,就需要定义承载wordbutton的容器,定义一个WordButtonGridView的控件

package com.crazy.guess.music.widget;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.GridView;import com.crazy.guess.music.R;import com.crazy.guess.music.model.WordButton;import com.crazy.guess.music.utils.Util;import java.util.ArrayList;import java.util.List;/** * 自定义控件,用于显示带选框中的文字按钮 * Created by vic_ma on 15/9/8. */public class WordButtonGridView extends GridView{    private Context mContext = null;    //待选文字框集合类    private List<WordButton> mWordButtons = new ArrayList<WordButton>();    //自定义待选文字框adapter    private WordButtonAdapter mAdapter = null;    public WordButtonGridView(Context context, AttributeSet attrs) {        super(context, attrs);        this.mContext = context;        mAdapter = new WordButtonAdapter();        setAdapter(mAdapter);    }    /**     * 更新数据     * @param wordButtons     */    public void updateData(List<WordButton> wordButtons){        this.mWordButtons = wordButtons;        setAdapter(mAdapter);        mAdapter.notifyDataSetChanged();    }    private class WordButtonAdapter extends BaseAdapter{       @Override       public int getCount() {           return mWordButtons.size();       }       @Override       public Object getItem(int i) {           return mWordButtons.get(i);       }       @Override       public long getItemId(int i) {           return 0;       }       @Override       public View getView(int postion, View view, ViewGroup viewGroup) {           //获取每一个WordButton           WordButton holder;           if(view == null){               view = Util.getView(mContext,R.layout.word_button_item);               holder = mWordButtons.get(postion);               holder.mButton = (Button)view.findViewById(R.id.item_button);               view.setTag(holder);           }else{               holder = (WordButton) view.getTag();           }           holder.mButton.setText(holder.mWordText);           return view;       }   }}
我们可以看到定义的WordButtonGridView继承自GridView, 并实现了显示需要的adapter,在adapter的getView方法中,返回的就是一个个自定义的WordButton,并且每个WordButton加载的布局是上面已经定义好的布局文件。

这里我将用到的Uti类贴出来,getView主要用于通过布局文件返回一个view

package com.crazy.guess.music.utils;import android.content.Context;import android.view.LayoutInflater;import android.view.View;/** * Created by vic_ma on 15/9/8. */public class Util {    public static View getView(Context context, int resId){        LayoutInflater inflater = LayoutInflater.from(context);        View view = View.inflate(context,resId,null);        return view;    }}
准备工作完成后,就需要在主界面布局文件中将其添加上, name_select.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="wrap_content"    android:layout_height="match_parent"    android:orientation="vertical">    <!--  文字已选框容器 -->    <LinearLayout        android:id="@+id/word_select_container"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginBottom="5dip"        android:gravity="center"        android:orientation="horizontal">    </LinearLayout>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@mipmap/game_line"/>    <!-- 自定义控件,文字待选框 -->    <com.crazy.guess.music.widget.WordButtonGridView        android:id="@+id/words_gridview"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_marginTop="5dip"        android:layout_weight="1"        android:gravity="center"        android:horizontalSpacing="2dip"        android:verticalSpacing="2dip"        android:paddingLeft="2dip"        android:paddingRight="2dip"        android:numColumns="8"        /></LinearLayout>
当然最后,还需要讲name_select.xml布局文件include到activity_main.xml中。

布局文件以及相关自定义控件准备好了之后,就需要在MainActivity.java中写好初始化的数据,并将其显示出来。

public class MainActivity extends Activity implements View.OnClickListener{    /**     * ===============Constants=================     */    private static final int OPTIONS_WORDS_SIZE = 24;    private static final int SELECTED_WORDS_SIZE = 4;    /**     * ===============view widget==============     */  .....    //自定义控件 文字待选框    private WordButtonGridView mWordButtonGridView = null;    /**     * ===============Animations===============     */  .....     * ==============Data======================     */  .....    //待选框的数据集合    private List<WordButton> mWordButtons = null;    //已选文字框数据集合    private List<WordButton> mSelectButtons = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化动画        initAnimations();        //初始化控件        initViews();        //初始化待选框中数据        initCurrentStageData();    }    /**     * 初始化控件     */    private void initViews(){        mButtonPlay = (ImageButton)findViewById(R.id.pan_button_start);        mViewPan = (ImageView) findViewById(R.id.pan_img_disc);        mViewBar = (ImageView) findViewById(R.id.pan_img_bar);        mWordButtonGridView = (WordButtonGridView) findViewById(R.id.words_gridview);        mButtonPlay.setOnClickListener(this);    }    /**     * 初始化动画     */    private void initAnimations() {       .....    }    /**     * 初始化待选框数据     */    private void initCurrentStageData(){        //生成已选文字框数据        mSelectButtons = getSelectedWords();        //设置已选文字框布局        setSelectedWordsLayout();        //生成待选框数据        mWordButtons = getOptionsData();        //将数据给自定义控件        mWordButtonGridView.updateData(mWordButtons);    }    /**     * 生成已选框文字数据     * @return     */    private List<WordButton> getSelectedWords(){        List<WordButton> selectWords = new ArrayList<WordButton>();        for(int i=0;i<SELECTED_WORDS_SIZE;i++){            View v =  Util.getView(this,R.layout.word_button_item);            WordButton wordButton = new WordButton();            wordButton.mButton = (Button) v.findViewById(R.id.item_button);            wordButton.mButton.setBackgroundResource(R.mipmap.game_wordblank);            wordButton.mButton.setTextColor(Color.WHITE);            selectWords.add(wordButton);        }        return selectWords;    }    /**     * 动态设置已选框布局显示     */    private void setSelectedWordsLayout(){        LinearLayout layoutContainer = (LinearLayout)findViewById(R.id.word_select_container);        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(40,40);        for(int i=0;i<mSelectButtons.size();i++){            layoutContainer.addView(mSelectButtons.get(i).mButton,params);        }    }    /**     * 生成待选框数据     * @return     */    private List<WordButton> getOptionsData(){        List<WordButton> wordButtons = new ArrayList<WordButton>();        //TODO 随机生成数据        for(int i=0;i<OPTIONS_WORDS_SIZE;i++){            WordButton wordButton = new WordButton();            wordButton.mWordText = "好";            wordButtons.add(wordButton);        }        return wordButtons;    }    @Override    public void onClick(View view) {        switch (view.getId()){            //播放            case R.id.pan_button_start:                handlePlayStart();              break;        }    }    /**     * 启动播放     */   private void handlePlayStart(){   .....}    @Override    protected void onPause() {        mViewPan.clearAnimation();        super.onPause();    }}

在initCurrentStatgeData方法中,分别将已选文字框和待选文字款的布局设置好,值得注意的是已选文字框是通过动态添加到LinearLayout中的。最后将待选文字框的初始化数据设置完成后,调用其updateData方法,就可以显示出来了。程序运行结果如之前显示所示。

源码下载

0 0
原创粉丝点击