一個很有意思的選擇表情DialogActivity
看效果圖:
彈出來的是一個Activity,所以在manifest中這樣宣告:
<activity android:name=".InputFaceActivity" android:theme="@android:style/Theme.Dialog"/>
下面程式碼是用來解析和儲存表情drawable的:
public class MessageFaceModel{ /** single instance of this class */ private static MessageFaceModel instance = null; /** context */ private boolean mInitialized = false; private HashMap<String,Bitmap> mFaceMap = new HashMap<String,Bitmap>(); private ArrayList<String> mFaceStrings = new ArrayList<String>(); private ArrayList<Bitmap> mFaceIcons = new ArrayList<Bitmap>(); /** * constructor */ private MessageFaceModel(){ } /** * Factory method */ public static synchronized MessageFaceModel getInstance(){ if(instance == null){ instance = new MessageFaceModel(); } return instance; } /** * initialize face data */ public void init(Context context){ if(mInitialized){ //initialize only once return; } mFaceMap.clear(); mFaceStrings.clear(); mFaceIcons.clear(); AssetManager assetManager = context.getAssets(); ArrayList<String> faces = new ArrayList<String>(); DocumentBuilderFactory docBuilderFactory = null; DocumentBuilder docBuilder = null; Document doc = null; try { docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilder = docBuilderFactory.newDocumentBuilder(); doc = docBuilder.parse(assetManager.open("message_face/MessageFace.xml")); Element root = doc.getDocumentElement(); NodeList nodeList = root.getElementsByTagName("string"); for(int i =0;i< nodeList.getLength();i++) { Node node = nodeList.item(i); String s = ""; NodeList list = node.getChildNodes(); if(list != null){ for(int j = 0; j < list.getLength(); j++){ s += list.item(j).getNodeValue(); } } faces.add(s); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ doc = null; docBuilder = null; docBuilderFactory = null; } int i; for(i = 0; i < faces.size(); ++i){ int index = i + 1; int id = context.getResources().getIdentifier( "msgface_" + index, "drawable", "com.pic.optimize"); try { Bitmap bm = BitmapFactory.decodeResource(context.getResources(),id); mFaceMap.put(faces.get(i), bm); mFaceStrings.add(faces.get(i)); mFaceIcons.add(bm); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } mInitialized = true; } public ArrayList<Bitmap> getFaceIcons(){ return mFaceIcons; } public ArrayList<String> getFaceStrings(){ return mFaceStrings; } public Bitmap getFaceIcon(String face){ if(mFaceMap != null){ return mFaceMap.get(face); }else{ return null; } } /** * find face string in TextView content and replace then with face icon */ public SpannableString ProcessTextForFace(String textContent){ if(textContent.length() == 0){ return null; } int searchStartPos = 0; SpannableString spannableString = new SpannableString(textContent); while(true){ int sPos = textContent.indexOf("(#", searchStartPos); if(sPos < 0){ break; } int ePos = textContent.indexOf(")", searchStartPos); if(ePos < 0){ break; } if (sPos >= ePos) { break; } //one symbol pair is found String face = textContent.substring(sPos, ePos + 1); Bitmap bm = getFaceIcon(face); if(bm != null){ spannableString.setSpan(new ImageSpan(bm), sPos, ePos + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } searchStartPos = ePos + 1; } return spannableString; } public void clear() { // TODO Auto-generated method stub mInitialized = false; mFaceMap.clear(); mFaceStrings.clear(); mFaceIcons.clear(); } }
然後我們寫Activity,xml檔案是:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="" android:layout_width="fill_parent" android:layout_height="300dp" android:minHeight="100dp" android:background="@drawable/face_list_bg"> <GridView xmlns:android="" android:id="@+id/input_face_gridview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="18dp" android:layout_marginRight="10dp" android:layout_marginTop = "18dp" android:layout_marginBottom = "30dp" android:numColumns="auto_fit" android:horizontalSpacing="10dp" android:verticalSpacing="15dp" android:columnWidth="50dp" android:stretchMode="columnWidth" android:gravity="center" android:layout_weight="1.0"> </GridView> <LinearLayout xmlns:android="" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button android:id="@+id/input_face_cancel_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/cancel_button_style"> </Button> </LinearLayout> </RelativeLayout>
gridview來顯示錶情:
@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); MessageFaceModel.getInstance().init(this); requestWindowFeature(Window.FEATURE_NO_TITLE); mWidth = this.getResources().getDimensionPixelSize(R.dimen.image_width); getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); setContentView(R.layout.input_face_activity); GridView gridView = (GridView) findViewById(R.id.input_face_gridview); gridView.setAdapter(new FaceListAdapter()); gridView.setOnItemClickListener(new FaceListOnItemClickListener()); Button cancelButton = (Button)findViewById(R.id.input_face_cancel_button); cancelButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View arg0) { finish(); } }); } private class FaceListAdapter extends BaseAdapter { public int getCount() { if(mMessageFaceModel.getFaceIcons() != null){ return mMessageFaceModel.getFaceIcons().size(); }else{ return 0; } } public Object getItem(int arg0) { return arg0; } public long getItemId(int arg0) { return arg0; } public View getView(int position, View convertView, ViewGroup parent) { ImageView view = new ImageView(InputFaceActivity.this); view.setImageBitmap(mMessageFaceModel.getFaceIcons().get(position)); view.setLayoutParams(new GridView.LayoutParams(mWidth, mWidth)); view.setScaleType(ImageView.ScaleType.CENTER); return view; } }
程式碼在
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3705/viewspace-2818542/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用 vite 構建一個表情選擇外掛Vite
- 一個很有意思的hook庫:react-hangerHookReact
- Java堆外快取(一個很有意思的應用)Java快取
- 一份很有意思的 GC logGC
- 一個很有意思的Python小案例,真的是城市套路深呀Python
- github 主頁可以 DIY 了,很有意思Github
- 很有用的 GCC 命令列選項GC命令列
- 一個非常老但是很有用的功能-閃回
- 有哪些鮮為人知,但是很有意思的網站?網站
- 介紹幾篇很有意思的計算機科普文章計算機
- 選擇 .NET 的 n 個理由
- win10系統怎麼使用Chrome新的表情符號選擇器Win10Chrome符號
- 一、選擇公司的形式:
- 選擇HHDESK的理由一
- 常見的webshell工具,你會選擇哪一個?Webshell
- 一個帶有權重的隨機選擇器隨機
- iOS 一個滑動選擇控制元件iOS控制元件
- MySQL innodb如何選擇一個聚簇索引MySql索引
- vue 手寫一個時間選擇器Vue
- cross-plateform 跨平臺應用程式-03-如果只選擇一個框架,應該選擇哪一個?ROSORM框架
- 除gRPC之外的另一個選擇,IceRPC-支援QUICRPCUI
- Nginx的另一個選擇 - Traefik 入手及簡單配置Nginx
- 一個開源、美觀的日期選擇器(bootstrap datepicker)boot
- 如何選擇一個適合發外鏈的論壇?
- 華瑞IT教育:IT行業是一個不錯的選擇行業
- 寫一個通用的冪等元件,我覺得很有必要元件
- 給《Laravel 中文文件》新增一個語言選擇選單Laravel
- 自定義一個仿拼多多地址選擇器
- 如何快速實現一個顏色選擇器
- openSUSE Leap 與 Tumbleweed,我該選擇哪一個
- 分享一個有意思的錯誤
- 怎麼樣選擇一個合適的虛擬主機
- CSS選擇器(一)CSS
- 探探社交、一對一交友APP不是偶然的選擇,而是社交市場的選擇APP
- 選擇同步雲盤工具?這些值得一試的優秀選擇!
- 一個用Python將影片變為表情包的工具Python
- select下拉選擇第一個選項為空白、option無法選中的解決辦法,
- 力軟下拉框預設選擇第一個