編輯:關於Android編程
原型圖和設計圖
800*480 —> 向下兼容 1280*720 —> 向上兼容圖片適配:
根據屏幕的分辨率,選擇drawable-xxxxx 圖片的名稱必須一致布局的適配:
layout-xxx, xxxx 是 高x寬(大乘小)如:layout-480x320 布局文件名稱一致尺寸的適配:
px: pexl 像素 dip/dp: denisity-independent pexl 自主密度的像素 ppi: pexl per inch 每英寸有多少個像素點 > 300dpi: dots per inch 每英寸可打印的點
ppi的計算:
ppi = 開根(寬的平方 + 高的平方) / inch ppi = 開根(480^2 + 320^2) / 3.5 = 164dpi: 480*320 3.5 1dp = 1px dpi : 160
公式 : px = dp * (dpi / 160)
dp = px / (dpi / 160);px自己想要的像素 dpi值 ,自己查閱(文檔)ldpi: 320x240
dp = 120 /(120/160) = 160dp
mdpi: 480x320
dp = 160 / ( 160 / 160) = 160dp
hdpi: 800x480
dp = 240 / (240/160) = 160dp
xhdpi: 1280x720
dp = 360 /(320/160) = 180dp
A set of six generalized densities:
ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
8. denisity : 像素密度(縮放比) denistity = px / dp;
1. dp = px / denistity;
通過代碼獲取手機相對應得像素,密度手機屏幕高度等相關信息:
DisplayMetris metrics=getResources().getDisplayMetrics();
float density=metrics.density;
float densityDpi=metrics.densityDpi;
代碼的適配(權重):
舉個例子:
//最外側的容器
LinearLayout container=new LinearLayout(this);
container.setOrientation(LinearLayout.VERTICAL);
LayoutParams params=new LayoutParams(LayoutParams.MATH_PARENT,LayoutParams.MATH_PARENT);
LinearLayout topLayout=new LinearLayout(this);
topLayout.setBackColor(Color.RED);
params.weight=1;
container.addView(topLayout,params);
LinearLayout buttomLayout=new LinearLayout(this);
buttomLayout.setBackColor(Color.RED);
params.weight=1;
container.addView(buttomLayout,params);
版本適配
通過判斷版本去寫代碼 android.jar它是在手機環境中的,不是在apk中
例如:
AsyncTask task=new AsyncTask(){
protected void doInBackgroup(void...params){
return null;
}
};
if(Build.VERSION.SDK_INT科大訊飛語音
聽 :
說 :
搜索:科大訊飛語音雲使用:
1. 注冊賬號
2. 創建應用
3. 使用服務
4. sdk下載
5. 集成
下面通過一個小案例來了解它的使用:語音機器人
通過科大訊飛文檔,先集成使用環境,抽出一個聽說的工具類
public class SpeekListenUtils
{
private Context mContext;
public SpeekListenUtils(Context context) {
this.mContext = context;
// 請勿在“=”與 appid 之間添加任務空字符或者轉義符
SpeechUtility.createUtility(context, SpeechConstant.APPID + "=57ab2dcc");//57ab2dcc為自己應用申請的appkey
}
//聽的功能
public void listen(RecognizerDialogListener mRecognizerDialogListener)
{
// 1.創建RecognizerDialog對象
RecognizerDialog mDialog = new RecognizerDialog(mContext, null);
// 2.設置accent、language等參數
mDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
mDialog.setParameter(SpeechConstant.ACCENT, "mandarin");
// 若要將UI控件用於語義理解,必須添加以下參數設置,設置之後onResult回調返回將是語義理解 //結果 //
// mDialog.setParameter("asr_sch", "1"); //
// mDialog.setParameter("nlp_version", "2.0");
// 3.設置回調接口
mDialog.setListener(mRecognizerDialogListener);
// 4.顯示dialog,接收語音輸入
mDialog.show();
}
//說的功能
public void speak(String text,SynthesizerListener mSynthesizerListener)
{
// 1.創建SpeechSynthesizer 對象, 第二個參數:本地合成時傳InitListener
SpeechSynthesizer mTts= SpeechSynthesizer.createSynthesizer(mContext, null);
// //2.合成參數設置,詳見《MSC Reference Manual》SpeechSynthesizer 類
// //設置發音人(更多在線發音人,用戶可參見 附錄13.2
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan"); //設置發音人
mTts.setParameter(SpeechConstant.SPEED, "50");//設置語速
mTts.setParameter(SpeechConstant.VOLUME, "80");//設置音量,范圍 0~100
mTts.setParameter(SpeechConstant.ENGINE_TYPE,
SpeechConstant.TYPE_CLOUD); //設置雲端
//設置合成音頻保存位置(可自定義保存位置),保存在“./sdcard/iflytek.pcm” //保存在 SD 卡需要在
// AndroidManifest.xml 添加寫 SD 卡權限 //僅支持保存為 pcm 和 wav
// 格式,如果不需要保存合成音頻,注釋該行代碼
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,"./sdcard/iflytek.pcm");
//3.開始合成
mTts.startSpeaking(text, mSynthesizerListener);
}
}
現在先來看看語音機器人的實際效果圖:問時:
————-
機器答時:
———–
在集成的sdk環境中,在聽的時候會自動彈出一個透明對話框,這個已經封裝好了如上圖。我們自要對著屏幕說就可以啦。現在來看看:
先初始化布局,這個布局分為一個按鈕,一個listView
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
初始化數據initData();
private void initData()
{
SpeekListenUtils utils=new SpeekListenUtils(this);
ListView mList=(ListView) findViewById(R.id.list_speak);
//設置數據
MyListAdapter adapter=new MyListAdapter();
mList.setAdapter(adapter);
}
給按鈕設置點擊事件
//點擊按鈕,開始說語音讓機器人聽
public void clickListen(View view){
utils.listen(new MyRecognizerDialogListener());
}
完成聽語音的監聽和數據的獲取:
private class MyRecognizerDialogListener implements RecognizerDialogListener{
@Override
public void onError(SpeechError arg0)
{
}
@Override
public void onResult(RecognizerResult arg0, boolean isLast)
{
String result=arg0.getResultString();
Log.i(TAG, "---"+result);
//解析json
Gson json=new Gson();
ListDataBean bean=json.fromJson(result, ListDataBean.class);
content += getResult(bean); //返回聽到的文字content初始化為空字符串
//判斷是否是最後一次
if(isLast){
//最後一次、問的話content------>convert
ConvertBean ask=new ConvertBean();
ask.type=0;
ask.text=content;
if(mDatas==null){
mDatas=new LinkedList();
}
mDatas.add(ask);
//清空content
content="";
//UI刷新
adapter.notifyDataSetChanged();
//回答
String text=ask.text;
ConvertBean answer=null;
Random adm=new Random();
int textSize=RobotRes.resText.length;
int icomSize=RobotRes.resIcon.length;
if(text.contains("美女")){//這裡可以做很多判斷
//bean
answer =new ConvertBean();
answer.type=1;
answer.img=RobotRes.resIcon[adm.nextInt(icomSize)];//隨機返回
answer.text=RobotRes.resText[adm.nextInt(textSize)];//隨機返回
}else{
answer =new ConvertBean();
answer.type=1;
answer.img=-1;
answer.text="不好意思,沒聽懂,請再說一遍!";
}
//說出來
utils.speak(answer.text, null);
mDatas.add(answer);
//UI刷新
adapter.notifyDataSetChanged();
//滑動到下面可見
mList.setSelection(adapter.getCount());
}
}
}
//獲取數據
public String getResult(ListDataBean bean)
{
List wsbean=bean.ws;
StringBuffer sb=new StringBuffer();
for(Wsbean ws:wsbean){
List cwbean=ws.cw;
for(Cwbean cw:cwbean){
sb.append(cw.w);
}
}
return sb.toString();
}
給listView設置適配器:
//適配器
class MyListAdapter extends BaseAdapter{
@Override
public int getCount()
{
if(mDatas!=null){return mDatas.size();}
return 0;
}
@Override
public Object getItem(int position)
{
return mDatas.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
//復用歷史的convertview
if(convertView==null){
convertView=View.inflate(getApplicationContext(), R.layout.list_item, null);
holder=new ViewHolder();
holder.mAskLinLayout=convertView.findViewById(R.id.ask_container);
holder.mAnswerRelLayout=convertView.findViewById(R.id.answer_container);
holder.asktext=(TextView) convertView.findViewById(R.id.ask_text);
holder.answertext=(TextView) convertView.findViewById(R.id.answer_text);
holder.answerimg=(ImageView) convertView.findViewById(R.id.answer_img);
convertView.setTag(holder);
}else{
holder=(ViewHolder) convertView.getTag();
}
//設置數據
ConvertBean data=mDatas.get(position);
if(data.type==0){
//問
holder.mAskLinLayout.setVisibility(View.VISIBLE);
holder.mAnswerRelLayout.setVisibility(View.GONE);
holder.asktext.setText(data.text);
}else{
//答
holder.mAskLinLayout.setVisibility(View.GONE);
holder.mAnswerRelLayout.setVisibility(View.VISIBLE);
holder.answertext.setText(data.text);
if(data.img!=-1){
holder.answerimg.setImageResource(data.img);
}
}
return convertView;
}
}
class ViewHolder{
View mAskLinLayout;
View mAnswerRelLayout;
TextView asktext;
TextView answertext;
ImageView answerimg;
}
在完成之前先創建問答在listView顯示的item布局:
下面是自己創建的資源文件,圖片放在drawable-hdpi中
public class RobotRes
{
public static int[] resIcon=new int[]{
R.drawable.p1,R.drawable.p2,
R.drawable.p3,R.drawable.p4,
R.drawable.p5,R.drawable.p6,
R.drawable.p7,R.drawable.p8,
R.drawable.p9,R.drawable.p10,
};
public static String[] resText=new String[]{
"專業辦證300年","天王蓋地虎",
"屌絲,朝前看吧","色狼,你的最愛",
"我愛你","看見你死而無憾了",
"世上有你相伴最好"
};
}
存儲數據的javabean:
public class ConvertBean
{
String text;
int img=-1;
int type=0;//0位問 ,1 為答
}
把獲得的數據解析的javabean:
public class ListDataBean
{
public int bg;
public int ed;
public boolean ls;
public int sn;
public List ws;
class Wsbean{
public int bg;
public List cw;
}
class Cwbean{
public double sc;
public String w;
}
}
到這裡,語音機器人就簡單完成了,這裡只是簡單介紹了語音sdk的集成和使用,具體的還需要多多研究。
項目中需要用到底欄導航欄,滑動或者點擊會切換上面的視圖,如圖: 這個效果使用Viewpager+Fragmen實現是主流方案,加入你之前對fragment
使用意圖傳遞數據的幾種方式 點此獲取完整代碼 我們除了要從活動返回數據,也常常要傳遞數據給活動。對此我們可以使用Intent對象將這些數據傳遞給目標活動。
實驗中只需要編寫相應的xml的代碼,java代碼不需要更改,因為我們這裡只是練習android的界面設計。線性布局:線性布局就是將各種控件按照行或者列依次進行排列。其中本
概述新版的音悅台 APP 播放頁面交互非常有意思,可以把播放器往下拖動,然後在底部懸浮一個小框,還可以左右拖動,然後回彈的時候也會有相應的效果,這種交互效果在頭條視頻和一