RongExtension.this.setPluginBoard()
方法;this.mPluginToggle.setOnClickListener(new OnClickListener() { public void onClick(View v) { if(RongExtension.this.mExtensionClickListener != null) { RongExtension.this.mExtensionClickListener.onPluginToggleClick(v, RongExtension.this); } RongExtension.this.setPluginBoard(); } });
private void setPluginBoard() { if(this.mPluginAdapter.isInitialized()) { if(this.mPluginAdapter.getVisibility() == 0) { //省略部分代碼 } else { //省略部分代碼 } } }
public void onAttachedToExtension(RongExtension extension) { this.mEditText = extension.getInputEditText(); Context context = extension.getContext(); RLog.i(TAG, "attach " + this.stack.size()); //mEditText編輯框存放到stack棧對象中 this.stack.push(this.mEditText); Resources resources = context.getResources(); try { this.types = resources.getStringArray(resources.getIdentifier("rc_realtime_support_conversation_types", "array", context.getPackageName())); } catch (NotFoundException var5) { ; } } //判斷棧大小,若是大於0出棧,並返回mEditText public void onDetachedFromExtension() { RLog.i(TAG, "detach " + this.stack.size()); if(this.stack.size() > 0) { this.stack.pop(); this.mEditText = this.stack.size() > 0?(EditText)this.stack.peek():null; } }
2.`getPluginModules方法`主要把功能插件對象--實現IPluginModule接口存放到ArrayList中,提供給外部使用;*
AMapNetworkLocationClient
存在後纔會把地理位置插件加到ArrayList;public List<IPluginModule> getPluginModules(ConversationType conversationType) { ArrayList pluginModuleList = new ArrayList(); ImagePlugin image = new ImagePlugin(); FilePlugin file = new FilePlugin(); pluginModuleList.add(image); String e; Class cls; try { //判斷高德定位服務類是否存在,存在的話根據ConversationType類型把位置共享插件與個人位置插件添加ArrayList中; e = "com.amap.api.netlocation.AMapNetworkLocationClient"; cls = Class.forName(e); if(cls != null) { CombineLocationPlugin constructor = new CombineLocationPlugin(); DefaultLocationPlugin recognizer = new DefaultLocationPlugin(); boolean typesDefined = false; if(this.types != null && this.types.length > 0) { String[] arr$ = this.types; int len$ = arr$.length; for(int i$ = 0; i$ < len$; ++i$) { String type = arr$[i$]; if(conversationType.getName().equals(type)) { typesDefined = true; break; } } } if(typesDefined) { pluginModuleList.add(constructor); } else if(this.types == null && conversationType.equals(ConversationType.PRIVATE)) { pluginModuleList.add(constructor); } else { pluginModuleList.add(recognizer); } } } catch (Exception var15) { RLog.i(TAG, "Not include AMap"); var15.printStackTrace(); } if(conversationType.equals(ConversationType.GROUP) || conversationType.equals(ConversationType.DISCUSSION) || conversationType.equals(ConversationType.PRIVATE)) { pluginModuleList.addAll(InternalModuleManager.getInstance().getExternalPlugins(conversationType)); } pluginModuleList.add(file); //判斷科大訊飛sdk是否存在,存在的話經過反射實例化語音識別插件並加入到ArraryList中 try { e = "com.iflytek.cloud.SpeechUtility"; cls = Class.forName(e); if(cls != null) { cls = Class.forName("io.rong.recognizer.RecognizePlugin"); Constructor var16 = cls.getConstructor(new Class[0]); IPluginModule var17 = (IPluginModule)var16.newInstance(new Object[0]); pluginModuleList.add(var17); } } catch (Exception var14) { RLog.i(TAG, "Not include Recognizer"); var14.printStackTrace(); } return pluginModuleList; }
mInitialized
布爾類型值與addPlugins
方法public class PluginAdapter { private static final String TAG = "PluginAdapter"; private List<IPluginModule> mPluginModules = new ArrayList(); private boolean mInitialized; public PluginAdapter() { } public boolean isInitialized() { return this.mInitialized; } //省略部分方法 public void addPlugins(List<IPluginModule> plugins) { for(int i = 0; plugins != null && i < plugins.size(); ++i) { this.mPluginModules.add(plugins.get(i)); } } //省略部分方法 public void bindView(ViewGroup viewGroup) { this.mInitialized = true; this.initView(viewGroup.getContext(), viewGroup); } private void initView(Context context, ViewGroup viewGroup) { //省略部分方法 } public int getVisibility() { return this.mPluginPager != null?this.mPluginPager.getVisibility():8; } //省略部分代碼 }
initPlugins方法
把插件加到PluginAdapter對象中;setPluginBoard方法
;長話多說,若是mPluginAdapter(插件適配器)未初始化,先進行初始化;private void setPluginBoard() { if(this.mPluginAdapter.isInitialized()) { if(this.mPluginAdapter.getVisibility() == 0) { View pager = this.mPluginAdapter.getPager(); if(pager != null) { pager.setVisibility(pager.getVisibility() == 8?0:8); } else { this.mPluginAdapter.setVisibility(8); this.mContainerLayout.setSelected(true); this.showInputKeyBoard(); } } else { this.mEmoticonToggle.setImageResource(drawable.rc_emotion_toggle_selector); if(this.isKeyBoardActive()) { this.getHandler().postDelayed(new Runnable() { public void run() { RongExtension.this.mPluginAdapter.setVisibility(0); } }, 200L); } else { this.mPluginAdapter.setVisibility(0); } this.hideInputKeyBoard(); this.hideEmoticonBoard(); this.mContainerLayout.setSelected(false); } } else { this.mEmoticonToggle.setImageResource(drawable.rc_emotion_toggle_selector); this.mPluginAdapter.bindView(this); this.mPluginAdapter.setVisibility(0); this.mContainerLayout.setSelected(false); this.hideInputKeyBoard(); this.hideEmoticonBoard(); } this.hideVoiceInputToggle(); this.mEditTextLayout.setVisibility(0); }
getPluginModules方法
提到的ImagePlugin
類是講解的重點;1 1.點擊「+」的時候插件功能已經可使用了,那麼說明在聊天界面渲染以前插件已經被創建起來,很容易,想到初始化聊天IM服務是最好的時機;html
//調用RongIM的public靜態init方法,參數呢是實例化的DefaultExtensionModule RongExtensionManager.getInstance().registerExtensionModule(new DefaultExtensionModule());
public void registerExtensionModule(IExtensionModule extensionModule) { if(mExtModules == null) { RLog.e("RongExtensionManager", "Not init in the main process."); } else if(extensionModule != null && !mExtModules.contains(extensionModule)) { RLog.i("RongExtensionManager", "registerExtensionModule " + extensionModule.getClass().getSimpleName()); if(mExtModules.size() <= 0 || !((IExtensionModule)mExtModules.get(0)).getClass().getCanonicalName().equals("com.jrmf360.rylib.modules.JrmfExtensionModule") && !((IExtensionModule)mExtModules.get(0)).getClass().getCanonicalName().equals("com.melink.bqmmplugin.rc.BQMMExtensionModule")) { mExtModules.add(extensionModule); } else { mExtModules.add(0, extensionModule); } extensionModule.onInit(mAppKey); } else { RLog.e("RongExtensionManager", "Illegal extensionModule."); } }
2 2.再看RongExtension的initData方法,把RongExtensionManager中的List
private void initData() { this.mExtensionModuleList = RongExtensionManager.getInstance().getExtensionModules(); this.mPluginAdapter = new PluginAdapter();//省略若干代碼 }
3 3.再看RongExtension的setConversation方法調用this.initPlugins(),噹噹噹的,調用了實例化插件對象的addPlugins把插件加入到其中,從而造成關聯;git
private void initPlugins() { Iterator i$ = this.mExtensionModuleList.iterator(); while(i$.hasNext()) { IExtensionModule module = (IExtensionModule)i$.next(); List pluginModules = module.getPluginModules(this.mConversationType); if(pluginModules != null && this.mPluginAdapter != null) { this.mPluginAdapter.addPlugins(pluginModules); } } }
public interface IPluginModule { Drawable obtainDrawable(Context var1); String obtainTitle(Context var1); void onClick(Fragment var1, EditExtension var2); void onActivityResult(int var1, int var2, Intent var3); }
public class ImagePlugin implements IPluginModule { ConversationType conversationType; String targetId; public ImagePlugin() { } //item的背景圖片 public Drawable obtainDrawable(Context context) { return ContextCompat.getDrawable(context, R.drawable.rc_ext_plugin_image_selector); } //item的插件標題 public String obtainTitle(Context context) { return context.getString(R.string.rc_plugin_image); } //item點擊事件 public void onClick(Fragment currentFragment, EditExtension extension) { String[] permissions = new String[]{"android.permission.READ_EXTERNAL_STORAGE"}; //這裏考慮android6.0權限變動,不只須要聲明權限,並且敏感權限須要容許時申請 if(PermissionCheckUtil.requestPermissions(currentFragment, permissions)) { this.conversationType = extension.getConversationType(); this.targetId = extension.getTargetId(); Intent intent = new Intent(currentFragment.getActivity(), PictureSelectorActivity.class); //回調Fragment 中的onActivityResult extension.startActivityForPluginResult(intent, 23, this); } } public void onActivityResult(int requestCode, int resultCode, Intent data) { } }
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == 102) { this.getActivity().finish(); } else { this.mRongExtension.onActivityPluginResult(requestCode, resultCode, data); } }
this.mFragment.startActivityForResult(intent, (position + 1 << 8) + (requestCode & 255));
上述代碼完成之後能夠經過回調ConversationFragment實現的`this.mExtensionClickListener.onImageResult(list, lat1);`方法發送圖片消息了,代碼就不貼了;