pjsip视频通信开发(上层应用)之数字键盘的制作

pjsip视频通信开发(上层应用)之EditText重写中我制作了一个显示输入内容的EditText,这里将制作一个数字键盘,其实跟计算器一样,最多的就是用TableLayout来实现,内部通过权重(weight)来实现布局的统一,上层实现按键事件触发回调实现内容的输出。

键盘布局:

<?xml version="1.0" encoding="utf-8"?>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <ImageButton
            android:id="@+id/button1"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_one"
            android:src="@drawable/dial_num_1" />

        <ImageButton
            android:id="@+id/button2"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_two"
            android:src="@drawable/dial_num_2" />

        <ImageButton
            android:id="@+id/button3"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_three"
            android:src="@drawable/dial_num_3" />
    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <ImageButton
            android:id="@+id/button4"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_four"
            android:src="@drawable/dial_num_4" />

        <ImageButton
            android:id="@+id/button5"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_five"
            android:src="@drawable/dial_num_5" />

        <ImageButton
            android:id="@+id/button6"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_six"
            android:src="@drawable/dial_num_6" />
    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <ImageButton
            android:id="@+id/button7"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_seven"
            android:src="@drawable/dial_num_7" />

        <ImageButton
            android:id="@+id/button8"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_eight"
            android:src="@drawable/dial_num_8" />

        <ImageButton
            android:id="@+id/button9"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_nine"
            android:src="@drawable/dial_num_9" />
    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <ImageButton
            android:id="@+id/buttonstar"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_star"
            android:src="@drawable/dial_num_star" />

        <ImageButton
            android:id="@+id/button0"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_zero"
            android:src="@drawable/dial_num_0" />

        <ImageButton
            android:id="@+id/buttonpound"
            style="@style/DialtactsDialpadButtonStyle"
            android:contentDescription="@string/description_image_button_pound"
            android:src="@drawable/dial_num_pound" />
    </TableRow>

</TableLayout>


显示效果如下:


布局设置好之后,我们就要调用布局,设置监听实现回调。

package com.jwzhangjie.pjsip.widgets;

import java.util.HashMap;
import java.util.Map;

import com.jwzhangjie.pjsip.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.ToneGenerator;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.ImageButton;

public class Dialpad extends FrameLayout implements OnClickListener {

	private OnDialKeyListener onDialKeyListener;

	public Dialpad(Context context) {
		super(context);
		initLayout(context);
	}

	public Dialpad(Context context, AttributeSet attrs) {
		super(context, attrs);
		initLayout(context);
	}

	private void initLayout(Context context) {
		LayoutInflater inflater = LayoutInflater.from(context);
		inflater.inflate(R.layout.dialpad, this, true);
	}

//	 Here we need a map to quickly find if the clicked button id is in the map
//	 keys,之所以这里不用SparseArrays,因为下面取值的方便
	@SuppressLint("UseSparseArrays")
	private static final Map<Integer, int[]> DIGITS_BTNS = new HashMap<Integer, int[]>();
	static {
		DIGITS_BTNS.put(R.id.button0, new int[] { ToneGenerator.TONE_DTMF_0,
				KeyEvent.KEYCODE_0 });
		DIGITS_BTNS.put(R.id.button1, new int[] { ToneGenerator.TONE_DTMF_1,
				KeyEvent.KEYCODE_1 });
		DIGITS_BTNS.put(R.id.button2, new int[] { ToneGenerator.TONE_DTMF_2,
				KeyEvent.KEYCODE_2 });
		DIGITS_BTNS.put(R.id.button3, new int[] { ToneGenerator.TONE_DTMF_3,
				KeyEvent.KEYCODE_3 });
		DIGITS_BTNS.put(R.id.button4, new int[] { ToneGenerator.TONE_DTMF_4,
				KeyEvent.KEYCODE_4 });
		DIGITS_BTNS.put(R.id.button5, new int[] { ToneGenerator.TONE_DTMF_5,
				KeyEvent.KEYCODE_5 });
		DIGITS_BTNS.put(R.id.button6, new int[] { ToneGenerator.TONE_DTMF_6,
				KeyEvent.KEYCODE_6 });
		DIGITS_BTNS.put(R.id.button7, new int[] { ToneGenerator.TONE_DTMF_7,
				KeyEvent.KEYCODE_7 });
		DIGITS_BTNS.put(R.id.button8, new int[] { ToneGenerator.TONE_DTMF_8,
				KeyEvent.KEYCODE_8 });
		DIGITS_BTNS.put(R.id.button9, new int[] { ToneGenerator.TONE_DTMF_9,
				KeyEvent.KEYCODE_9 });
		DIGITS_BTNS.put(R.id.buttonpound, new int[] {
				ToneGenerator.TONE_DTMF_P, KeyEvent.KEYCODE_POUND });
		DIGITS_BTNS.put(R.id.buttonstar, new int[] { ToneGenerator.TONE_DTMF_S,
				KeyEvent.KEYCODE_STAR });
	};

	/**
	 * SparseArray这个是android提供的,可以替换HashMap,来提高效率
	 */
	private static final SparseArray<String> DIGITS_NAMES = new SparseArray<String>();

	static {
		DIGITS_NAMES.put(R.id.button0, "0");
		DIGITS_NAMES.put(R.id.button1, "1");
		DIGITS_NAMES.put(R.id.button2, "2");
		DIGITS_NAMES.put(R.id.button3, "3");
		DIGITS_NAMES.put(R.id.button4, "4");
		DIGITS_NAMES.put(R.id.button5, "5");
		DIGITS_NAMES.put(R.id.button6, "6");
		DIGITS_NAMES.put(R.id.button7, "7");
		DIGITS_NAMES.put(R.id.button8, "8");
		DIGITS_NAMES.put(R.id.button9, "9");
		DIGITS_NAMES.put(R.id.buttonpound, "pound");
		DIGITS_NAMES.put(R.id.buttonstar, "star");
	};

	public interface OnDialKeyListener {

		/**
		 * Called when the user make an action
		 * 
		 * @param keyCode
		 *            keyCode pressed
		 * @param dialTone
		 *            corresponding dialtone
		 */
		void onTrigger(int keyCode, int dialTone);
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();

		for (int buttonId : DIGITS_BTNS.keySet()) {
			ImageButton button = (ImageButton) findViewById(buttonId);
			if (button != null) {
				button.setOnClickListener(this);
			}
		}
	}

	/**
	 * Registers a callback to be invoked when the user triggers an event.
	 * 
	 * @param listener
	 *            the OnTriggerListener to attach to this view
	 */
	public void setOnDialKeyListener(OnDialKeyListener listener) {
		onDialKeyListener = listener;
	}

	private void dispatchDialKeyEvent(int buttonId) {
		if (onDialKeyListener != null && DIGITS_BTNS.containsKey(buttonId)) {
			int[] datas = DIGITS_BTNS.get(buttonId);
			onDialKeyListener.onTrigger(datas[1], datas[0]);
		}
	}

	@Override
	public void onClick(View v) {
		dispatchDialKeyEvent(v.getId());
	}
}


我们看看上面的代码:

1、initLayout来解析布局之后

2、onFinishInflate来设置按钮的点击事件

3、onClick处理点击事件,通过dispatchDialKeyEvent来实现分发事件

4、dispatchDialKeyEvent来根据不同的id,来设置回调onDialKeyListener.onTrigger,所以在实现Dialpad后,要实现OnDialKeyListener接口

原文地址:https://www.cnblogs.com/pangblog/p/3395342.html