public class AttachFragment extends Fragment {

    @BindView(R.id.local_img_list)RecyclerView mLocalImgList;
    @BindView(R.id.ll_dots) LinearLayout mLayoutDots; //功能面板小圆点容器
    @BindView(R.id.panel_viewpager) ViewPager mPanelVP;//功能面板显示icon的容器
    //功能面板容器
    private ArrayList<View> panelViews = null;

    public static AttachFragment newInstance() {

        Bundle args = new Bundle();

        AttachFragment fragment = new AttachFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_attach,container,false);
        ButterKnife.bind(this,root);
        initView();
        return root;
    }

    private void initView(){
        mLocalImgList.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL,false));
        mLocalImgList.setItemAnimator(new DefaultItemAnimator());
        ImageModel.LocalImgAdapter adapter = new ImageModel.LocalImgAdapter(getActivity());
        mLocalImgList.setAdapter(adapter);
        //加载本地图库
        ImageModel.AttachPhotoLoaderCallback callback = new ImageModel.AttachPhotoLoaderCallback(getActivity(), adapter);
        getLoaderManager().initLoader(0, null, callback);

        //一页显示4个 算出要展示几页
        int panelPageNum = ChatPanelUtils.getPageNum(ChatPanelUtils.iconId.length, 4);
        //初始化小圆点
        ChatPanelUtils.initDots(panelPageNum,mLayoutDots,getActivity());
        //有几页加载几个view
        for (int j = 0; j < panelPageNum; j++) {
            if (panelViews == null) {
                panelViews = new ArrayList<View>();
            }
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            panelViews.add(inflater.inflate(R.layout.item_viewpager_panel, null));
        }
        ChatPanelUtils.instantiatedView(panelPageNum,ChatPanelUtils.iconId.length,4,panelViews,getActivity());
        mPanelVP.setOnPageChangeListener(new ChatPanelUtils.pageChangeListener(panelPageNum,getActivity()));
        mPanelVP.setAdapter(new ChatPanelUtils.PanelViewAdapter(panelViews));
    }




} public class LovedEmojiStyle implements EmojiStyle {

    LovedEmojicons emojicons;

    public LovedEmojiStyle() {
        emojicons = new LovedEmojicons();
    }

    @Override
    public String getStyleName() {
        return "loved";
    }

    @Override
    public int getStyleIcon() {
        return R.drawable.sg001;
    }

    @Override
    public View getStyleIconView(Context context) {
        ImageButton image = new ImageButton(context);
        image.setImageResource(R.drawable.sg003);
        image.setBackgroundResource(R.drawable.love_emojicon);
        image.setLayoutParams(new ViewGroup.LayoutParams(200, ViewGroup.LayoutParams.MATCH_PARENT));
        return image;
    }

    @Override
    public List getEmojiData() {
        return emojicons.getEmojis();
    }

    @Override
    public EmojiFragment getCustomFragment(int index) {
        return new LovedEmojiFragment<>();
    }

    @Override
    public PageEmojiStyle getPagerData(int index) {
        return new LovedPageEmojiStyle();
    }

    @Override
    public EmojiInterceptor getEmojiInterceptor() {
        return new LovedEmojiInterceptor();
    }
} public class EasyInputManagerImpl implements EasyInputManager {
    private Context mContext;
    private IMERootLayout mImeRootLayout;
    private IKeyboardManager mKeyboardManager;
    private IPanelLayout mIPanelLayout;
    private IPanelContentManager mPanelContentManager;
    private volatile Builder mBuilder;

    private EasyInputManagerImpl(Activity activity){
        this(activity,false);
    }

    /**
     *  注意manifest里面设置的属性会失效，默认被设置成：
     *  WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
     *          | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_（HIDDEN or VISIBLE)
     * @param activity
     * @param isKeyboardShow 进入activity时，输入法默认是否显示
     */
    private EasyInputManagerImpl(Activity activity,boolean isKeyboardShow){
        mContext = activity;
        mKeyboardManager = new KeyboardManagerImpl(activity);
        mIPanelLayout = new IMEPanelLayout(activity,mKeyboardManager);
        mPanelContentManager = PanelContentManager.newInstance(mContext,mIPanelLayout);
        mImeRootLayout = new IMERootLayout(activity,mKeyboardManager, mIPanelLayout.getPanel(),isKeyboardShow);
    }

    /**
     * 调用此方法默认会关闭输入法, 注意manifest里面设置的属性会失效，默认被设置成
     *      WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
     *          | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
     * @param activity
     * @return
     */
    public static EasyInputManager newInstance(Activity activity){
        return new EasyInputManagerImpl(activity);
    }

    /**
     * @param isKeyboardShow  true 默认输入打开
     */
    public static EasyInputManager newInstance(Activity activity,boolean isKeyboardShow){
        return new EasyInputManagerImpl(activity,isKeyboardShow);
    }

    @Override
    public void openKeyboard(View view) {
        mKeyboardManager.openKeyboard(view);
    }

    @Override
    public void closeKeyboard(View view) {
        mKeyboardManager.closeKeyboard(view);
    }

    @Override
    public void openPanel() {
        openPanel(null);
    }

    @Override
    public void openPanel(String tag) {
        mPanelContentManager.openPanel(tag);
        if(mKeyboardManager.isKeyboardShowing()){
            mKeyboardManager.closeKeyboard((Activity) mContext);
        }
    }

    @Override
    public void closePanel() {
        mPanelContentManager.closePanel();
    }

    @Override
    public void setTouchBlankAutoHideIME(boolean autoHideIME, int offsetPixel) {
        mImeRootLayout.setTouchBlankAutoHideIME(autoHideIME,offsetPixel);
    }

    @Override
    public void addFragmentToPanel(String tag, Fragment panelFragment) {
        mPanelContentManager.addContent(tag,panelFragment);
    }

    @Override
    public void removeFragmentToPanel(String tag) {
        mPanelContentManager.removeContent(tag);
    }

    @Override
    public void addViewToPanel(String tag, View panelView) {
        mPanelContentManager.addContent(tag,panelView);
    }

    @Override
    public void removeViewToPanel(String tag) {
        mPanelContentManager.removeContent(tag);
    }

    @Override
    public void addDefaultEmoji(String tag,EmojiconEditText emojiconEditText) {
        getEmojiBuilder()
                .setTag(tag)
                .setEmojiconEditText(emojiconEditText)
                .addEmojiStyle(new PeopleStyle())
                .addEmojiStyle(new NatureStyle())
                .build();
    }

    public Builder getEmojiBuilder(){
        if(mBuilder == null){
            synchronized (this) {
                if(mBuilder == null) {
                    mBuilder = new Builder((Activity) mContext,mPanelContentManager);
                }
            }
        }
        return mBuilder;
    }

    @Override
    public String getCurrentPanelDisplayTag() {
        return mPanelContentManager.getCurrentPanelDisplayTag();
    }

    @Override
    public boolean isKeyboardShowing() {
        return mKeyboardManager.isKeyboardShowing();
    }

    @Override
    public void addOnKeyboardIMEListener(OnKeyboardListener listener) {
        mImeRootLayout.addOnKeyboardIMEListener(listener);
    }

    @Override
    public void addOnPanelListener(OnPanelListener listener) {
        mIPanelLayout.addOnPanelListener(listener);
    }

    public static class Builder<T extends Parcelable>{
        Activity activity;
        EmojiStylesFragment fragment;
        IPanelContentManager panelContentManager;
        EmojiStyleWrapperManager manger;
        EmojiconEditText text;
        String tag;

        public Builder(Activity activity,IPanelContentManager panelContentManager){
            this.activity = activity;
            this.panelContentManager = panelContentManager;
            manger = new EmojiStyleWrapperManager(activity);
        }

        public Builder setTag(String tag){
            this.tag = tag;
            return this;
        }

        public Builder setEmojiconEditText(EmojiconEditText emojiconEditText){
            text = emojiconEditText;
            return this;
        }

        public Builder addEmojiStyle(EmojiStyle style){
            manger.addEmojiStyle(style);
            return this;
        }

        /**
         *增加底部按钮view,比如搜索
         * @param front  true,  放在普通表情最前面，
         *               false 放在普通表情最后面
         */
        public Builder addBottomTypeView(View view, boolean front, View.OnClickListener listener){
            manger.addBottomTypeView(view, front, listener);
            return this;
        }

        /**
         *增加底部按钮view,比如搜索, 默认放在普通表情最后面
         */
        public Builder addBottomTypeView(View view, View.OnClickListener listener){
            manger.addBottomTypeView(view, false, listener);
            return this;
        }

        public Builder addEmojiStyle(int position, EmojiStyle style){
            manger.addEmojiStyle(position,style);
            return this;
        }

        public Builder deleteEmojiStyle(String tag){
            manger.deleteEmojiStyle(tag);
            return this;
        }

        /**
         * 设置底部tab栏背景颜色
         */
        public Builder setTabViewBackgroundColor(int color){
            manger.setTabViewBackgroundColor(color);
            return this;
        }

        /**
         * 设置底部tab栏分割线颜色， -1，去掉分割线
         */
        public Builder setTabViewDividerColor(int color){
            manger.setTabViewDividerColor(color);
            return this;
        }

        /**
         * 设置表情指示器默认图片
         * @return
         */
        public Builder setIndicatorDefaultImageResource(@DrawableRes int resId){
            manger.setIndicatorDefaultImageResource(resId);
            return this;
        }

        /**
         * 设置表情指示器选中图片
         * @return
         */
        public Builder setIndicatorSelectedImageResource(@DrawableRes int resId){
            manger.setIndicatorSelectedImageResource(resId);
            return this;
        }

        public void updateEmojiStyle(EmojiStyle style){
            manger.updateStyle(style);
        }

        public void build(){
            if(TextUtils.isEmpty(tag)){
                throw new RuntimeException("please invoke setTag() method first to set panel tag !!!");
            }
            if(fragment != null){
                throw new RuntimeException("don't need invoke build() method twice to the same Builder instance !!!");
            }
            EmojiStylesFragment fragment = (EmojiStylesFragment) ((FragmentActivity)activity)
                    .getSupportFragmentManager()
                    .findFragmentByTag(tag);
            if(fragment == null) {
                fragment = EmojiStylesFragment.newInstance();
            }
            if(text != null) {
                fragment.setEmojiconEditText(text);
            }
            fragment.setEmojiStyleWrapperManager(manger);
            panelContentManager.addContent(tag,fragment);
        }
    }
} public interface EasyInputManager {
    void openKeyboard(View view);
    void closeKeyboard(View view);
    void openPanel();
    void openPanel(String tag);
    void closePanel();
    void addOnPanelListener(OnPanelListener listener);
    void addOnKeyboardIMEListener(OnKeyboardListener listener);
    void setTouchBlankAutoHideIME(boolean autoHideIME, int offsetPixel);
    void addFragmentToPanel(String tag, Fragment panelFragment);
    void removeFragmentToPanel(String tag);
    void addViewToPanel(String tag, View panelView);
    void removeViewToPanel(String tag);
    void addDefaultEmoji(String tag,EmojiconEditText emojiconEditText);
    EasyInputManagerImpl.Builder getEmojiBuilder();
    String getCurrentPanelDisplayTag();
    boolean isKeyboardShowing();
} public interface OnKeyboardListener {
    void onKeyboardDisplay(boolean isShowing);
} public interface OnPanelListener {
    void onPanelDisplay(boolean isShowing);
} public interface EmojiStyle<T extends Parcelable> {
    /**
     * 名称tag, 必须唯一
     */
    String getStyleName();

    /**
     * 底部tab的图标
     */
    int getStyleIcon();

    /**
     * 底部tab的图标， 如果不为空，优先使用， 如果为空则使用 getStyleIcon() 返回的图标，
     * tab 被选中时会调用view的 selected 事件
     */
    View getStyleIconView(Context context);

    /**
     * 所有emoji的数据源
     */
    List<T> getEmojiData();

    /**
     * 自定义的emoji显示页面， 一个 EmojiFragment 页面对应 一个 PageEmojiStyle 对象
     * EmojiFragment 为展示页面， PageEmojiStyle 为一个页面的数据源
     *
     * @param index
     * @return
     */
    EmojiFragment getCustomFragment(int index);

    /**
     * 一个显示页面的数据源
     *
     * @param index
     * @return
     */
    PageEmojiStyle getPagerData(int index);

    /**
     * 文本拦截事件， 用于处理自定义表情
     *
     * @return
     */
    EmojiInterceptor getEmojiInterceptor();
} public class EmojiconEditText extends AppCompatEditText {
    private int mEmojiconSize;
    private int mEmojiconAlignment;
    private int mEmojiconTextSize;
    private boolean mUseSystemDefault = false;

    public EmojiconEditText(Context context) {
        super(context);
        mEmojiconSize = (int) getTextSize();
        mEmojiconTextSize = (int) getTextSize();
    }

    public EmojiconEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public EmojiconEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.Emojicon);
        mEmojiconSize = (int) a.getDimension(R.styleable.Emojicon_emojiconSize, getTextSize());
        mEmojiconAlignment = a.getInt(R.styleable.Emojicon_emojiconAlignment, DynamicDrawableSpan.ALIGN_BASELINE);
        mUseSystemDefault = a.getBoolean(R.styleable.Emojicon_emojiconUseSystemDefault, false);
        a.recycle();
        mEmojiconTextSize = (int) getTextSize();
        addTextChangedListener(new EmojiTextWatcher(getContext(),mEmojiconSize,mEmojiconAlignment,mEmojiconTextSize,mUseSystemDefault));
        setText(getText());
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
    }

    /**
     * Set the size of emojicon in pixels.
     */
    public void setEmojiconSize(int pixels) {
        mEmojiconSize = pixels;
        setText(getText());
    }


    /**
     * Set whether to use system default emojicon
     */
    public void setUseSystemDefault(boolean useSystemDefault) {
        mUseSystemDefault = useSystemDefault;
        setText(getText());
    }
} public class Emojicon implements Parcelable {
    @IntDef({DynamicDrawableSpan.ALIGN_BASELINE, DynamicDrawableSpan.ALIGN_BOTTOM})
    public @interface Alignment {
    }

    @IntDef({TYPE_UNDEFINED, TYPE_PEOPLE, TYPE_NATURE, TYPE_OBJECTS, TYPE_PLACES, TYPE_SYMBOLS})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Type {
    }

    public static final int TYPE_UNDEFINED = 0;
    public static final int TYPE_PEOPLE = 1;
    public static final int TYPE_NATURE = 2;
    public static final int TYPE_OBJECTS = 3;
    public static final int TYPE_PLACES = 4;
    public static final int TYPE_SYMBOLS = 5;

    public static Emojicon[] getEmojicons(@Type int type) {
        switch (type) {
            case TYPE_PEOPLE:
                return People.DATA;
            case TYPE_NATURE:
                return Nature.DATA;
            case TYPE_OBJECTS:
                return Objects.DATA;
            case TYPE_PLACES:
                return Places.DATA;
            case TYPE_SYMBOLS:
                return Symbols.DATA;
        }
        throw new IllegalArgumentException("Invalid emojicon type: " + type);
    }

    public static final Creator<Emojicon> CREATOR = new Creator<Emojicon>() {
        @Override
        public Emojicon createFromParcel(Parcel in) {
            return new Emojicon(in);
        }

        @Override
        public Emojicon[] newArray(int size) {
            return new Emojicon[size];
        }
    };

    private int icon;

    private char value;

    private String emoji;

    public Emojicon(int icon, char value, String emoji) {
        this.icon = icon;
        this.value = value;
        this.emoji = emoji;
    }

    public Emojicon(Parcel in) {
        this.icon = in.readInt();
        this.value = (char) in.readInt();
        this.emoji = in.readString();
    }

    private Emojicon() {
    }

    public Emojicon(String emoji) {
        this.emoji = emoji;
    }

    public static Emojicon fromResource(int icon, int value) {
        Emojicon emoji = new Emojicon();
        emoji.icon = icon;
        emoji.value = (char) value;
        return emoji;
    }

    public static Emojicon fromCodePoint(int codePoint) {
        Emojicon emoji = new Emojicon();
        emoji.emoji = newString(codePoint);
        return emoji;
    }

    public static Emojicon fromChar(char ch) {
        Emojicon emoji = new Emojicon();
        emoji.emoji = Character.toString(ch);
        return emoji;
    }

    public static Emojicon fromChars(String chars) {
        Emojicon emoji = new Emojicon();
        emoji.emoji = chars;
        return emoji;
    }

    public static final String newString(int codePoint) {
        if (Character.charCount(codePoint) == 1) {
            return String.valueOf(codePoint);
        } else {
            return new String(Character.toChars(codePoint));
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(icon);
        dest.writeInt(value);
        dest.writeString(emoji);
    }

    public char getValue() {
        return value;
    }

    public int getIcon() {
        return icon;
    }

    public String getEmoji() {
        return emoji;
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof Emojicon && emoji.equals(((Emojicon) o).emoji);
    }

    @Override
    public int hashCode() {
        return emoji.hashCode();
    }

} public class ObjectsStyle implements EmojiStyle {

    List<Emojicon> emojiconList;
    public ObjectsStyle(){
        emojiconList = new ArrayList<>(Arrays.asList(Emojicon.getEmojicons(Emojicon.TYPE_OBJECTS)));
    }

    @Override
    public String getStyleName() {
        return "object";
    }

    @Override
    public int getStyleIcon() {
        return R.drawable.ic_emoji_bell;
    }

    @Override
    public View getStyleIconView(Context context) {
        return null;
    }

    @Override
    public List<Emojicon> getEmojiData() {
        return emojiconList;
    }

    @Override
    public EmojiFragment getCustomFragment(int index) {
        return new EmojiconFragment();
    }

    @Override
    public PageEmojiStyle getPagerData(int index) {
        return new EmojiconPageEmojiStyle();
    }

    @Override
    public EmojiInterceptor getEmojiInterceptor() {
        return null;
    }
}
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.nicky.easyemoji.fragments.AttachFragment;
import org.nicky.easyemoji.lovedEmoji.LovedEmojiStyle;
import org.nicky.libeasyemoji.EasyInput.EasyInputManagerImpl;
import org.nicky.libeasyemoji.EasyInput.interfaces.EasyInputManager;
import org.nicky.libeasyemoji.EasyInput.interfaces.OnKeyboardListener;
import org.nicky.libeasyemoji.EasyInput.interfaces.OnPanelListener;
import org.nicky.libeasyemoji.emoji.interfaces.EmojiStyle;
import org.nicky.libeasyemoji.emojicon.EmojiconEditText;
import org.nicky.libeasyemoji.emojicon.emoji.Emojicon;
import org.nicky.libeasyemoji.emojicon.emoji.ObjectsStyle;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
package org.nicky.easyemoji;




public class MainActivity extends AppCompatActivity {

    @BindView(R.id.emoji_input_txt)
    EmojiconEditText emojiconEditText;
    @BindView(R.id.emojicon_switch)
    CheckBox emojiSwitch;
    @BindView(R.id.close_keyboard)
    Button closeKeyboard;
    @BindView(R.id.open_keyboard)
    Button openKeyboard;
    @BindView(R.id.close_panel)
    Button closePanel;
    @BindView(R.id.open_panel)
    Button openPanel;
    @BindView(R.id.add_panel)
    Button addPanel;
    @BindView(R.id.delete_panel)
    Button deletePanel;
    @BindView(R.id.attach)
    ImageView attach;
    @BindView(R.id.add_emoji)
    Button addEmoji;
    @BindView(R.id.delete_emoji)
    Button deleteEmoji;
    @BindView(R.id.add_a_emoji)
    Button addOneEmoji;
    @BindView(R.id.delete_a_emoji)
    Button deleteOneEmoji;
    @BindView(R.id.publish)
    TextView publish;
    @BindView(R.id.emoji_txt)
    TextView txt;

    protected EasyInputManager mEasyInputManager;
    private EmojiStyle category = new ObjectsStyle();
    private EmojiStyle lovedEmoji = new LovedEmojiStyle();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int hasPer = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
            if(hasPer != PackageManager.PERMISSION_GRANTED){
                requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1000);
            }
        }


        mEasyInputManager = EasyInputManagerImpl.newInstance(this);
        mEasyInputManager.addOnPanelListener(new changePanelListener());
        mEasyInputManager.addOnKeyboardIMEListener(new changeKeyboardListener());
        mEasyInputManager.setTouchBlankAutoHideIME(true,dip2px(this, 50));
        mEasyInputManager.addFragmentToPanel("attach", AttachFragment.newInstance());