软件编程
位置:首页>> 软件编程>> Android编程>> Android仿直播类app赠送礼物功能

Android仿直播类app赠送礼物功能

作者:hongxue8888  发布时间:2023-07-26 05:06:17 

标签:android,直播,赠送礼物
目录
  • 直播界面

  • 滑动隐藏效果

  • 用户交互页实现

    • 礼物进入时动画

    • 礼物移出动画

  • 开启定时清理礼物列表

    直播界面

    实现的是播放本地的视频文件:


    /**
    * 直播界面,用于对接直播功能
    */
    public class LiveFrag extends Fragment {

    private ImageView img_thumb;
    private VideoView video_view;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.frag_live, null);
    img_thumb = view.findViewById(R.id.img_thumb);
    img_thumb.setVisibility(View.GONE);
    video_view = view.findViewById(R.id.video_view);
    video_view.setVisibility(View.VISIBLE);
    video_view.setVideoURI(Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.video_1));
    video_view.start();
    video_view.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
    video_view.setVideoURI(Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.video_1));
    //或 //mVideoView.setVideoPath(Uri.parse(_filePath));
    video_view.start();
    }
    });
    return view;
    }
    }

    布局文件 frag_live.xml 如下:


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <VideoView
    android:id="@+id/video_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false"
    android:focusable="false"
    android:visibility="gone" />
    <ImageView
    android:id="@+id/img_thumb"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false"
    android:focusable="false"
    android:scaleType="centerCrop"
    android:src="@mipmap/img_video_1"
    android:visibility="visible" />
    </LinearLayout>

    滑动隐藏效果

    需要实现的效果如下:

    Android仿直播类app赠送礼物功能

    自定义DialogFragment,使用ViewPager,第一个为空的Fragment,第二个为我们需要的Fragment,左右滑动来切换显示和隐藏效果。

    观众功能交互页面 InteractiveFrag 如下:


    /**
    * 观众功能交互页面, 滑动隐藏效果
    */
    public class InteractiveFrag extends DialogFragment {

    public View view;
    public Context myContext;
    private ViewPager vp_interactive;
    private LayerFrag layerFrag;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.frag_interactive, null);
    // 初始化
    initView();
    initData();
    return view;
    }

    /**
    * 初始化View
    */
    public void initView() {
    vp_interactive = view.findViewById(R.id.vp_interactive);
    }

    /**
    * 初始化数据
    */
    public void initData() {
    // EmptyFrag:什么都没有
    // LayerFrag:交互界面
    // 这样就达到了滑动隐藏交互的需求
    vp_interactive.setAdapter(new FragmentPagerAdapter(getChildFragmentManager()) {
    @Override
    public int getCount() {
    return 2;
    }

    @Override
    public Fragment getItem(int position) {
    if (position == 0) {
    return new EmptyFrag(); // 返回空界面的fragment
    } else if (position == 1) {
    return layerFrag = new LayerFrag(); // 返回交互界面的frag
    } else { // 设置默认

    return new EmptyFrag();
    }
    }
    });
    // 设置默认显示交互界面
    vp_interactive.setCurrentItem(1);

    // 同时将界面改为resize已达到软键盘弹出时Fragment不会跟随移动
    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

    // 设置DialogFragment的样式,这里的代码最好还是用我的,大家不要改动
    Dialog dialog = new Dialog(getActivity(), R.style.MainDialog) {

    @Override
    public void onBackPressed() {
    super.onBackPressed();
    getActivity().finish();
    }
    };
    return dialog;
    }
    }

    frag_interactive.xml文件如下:


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <androidx.viewpager.widget.ViewPager
    android:id="@+id/vp_interactive"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </LinearLayout>

    用户交互页 LayerFrag:


    public class LayerFrag extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.frag_layer, null);
    }
    }

    frag_layer:


    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
    android:id="@+id/ll_anchor"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingLeft="10dp"
    android:paddingTop="10dp">
    <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:background="@drawable/bg_radius_top_black"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:paddingLeft="55dp"
    android:paddingTop="2dp"
    android:paddingRight="10dp"
    android:paddingBottom="2dp">
    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="十三妹哦"
    android:textColor="@android:color/white"
    android:textSize="12sp" />
    <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">
    <ImageView
    android:layout_width="35dp"
    android:layout_height="20dp"
    android:src="@drawable/hani_icon_tag_exp" />
    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:text="17万"
    android:textColor="@android:color/white"
    android:textSize="10sp" />
    </LinearLayout>
    </LinearLayout>
    <com.hongx.zhibo.utils.CircleImageView
    android:id="@+id/lv_anchorIcon"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:src="@drawable/zf"
    app:border_color="@color/colorWhite"
    app:border_width="1dp" />
    </RelativeLayout>
    <com.hongx.zhibo.utils.HorizontalListView
    android:id="@+id/hlv_audience"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    android:layout_marginLeft="10dp" />
    </LinearLayout>
    <RelativeLayout
    android:id="@+id/rl_num"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/ll_anchor"
    android:layout_marginTop="5dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">
    <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_radius_bottom_pink"
    android:gravity="center_vertical"
    android:paddingLeft="10dp"
    android:paddingTop="2dp"
    android:paddingRight="10dp"
    android:paddingBottom="2dp">
    <ImageView
    android:layout_width="20dp"
    android:layout_height="10dp"
    android:src="@drawable/molive_icon_charm_lv_20" />
    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:text="小时榜单第5名"
    android:textColor="#fff"
    android:textSize="10sp" />
    </LinearLayout>
    <TextView
    android:id="@+id/tv_momocode"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:background="@drawable/bg_radius_top_black"
    android:paddingLeft="10dp"
    android:paddingTop="2dp"
    android:paddingRight="10dp"
    android:paddingBottom="2dp"
    android:text="MoMo: 12345678"
    android:textColor="@android:color/white"
    android:textSize="10sp" />
    </RelativeLayout>
    <LinearLayout
    android:id="@+id/ll_gift_group"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/lv_message"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:animateLayoutChanges="true"
    android:gravity="top"
    android:orientation="vertical" />
    <ListView
    android:id="@+id/lv_message"
    android:layout_width="230dp"
    android:layout_height="150dp"
    android:layout_above="@+id/fl_bottom"
    android:layout_marginLeft="10dp"
    android:cacheColorHint="#00000000"
    android:divider="@null"
    android:dividerHeight="5dp"
    android:listSelector="#00000000"
    android:scrollbarStyle="outsideOverlay"
    android:scrollbars="none"
    android:transcriptMode="normal" />
    <FrameLayout
    android:id="@+id/fl_bottom"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:layout_alignParentStart="true"
    android:layout_alignParentBottom="true">
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">
    <Button
    android:id="@+id/tv_chat"
    android:layout_width="40dp"
    android:layout_height="70dp"
    android:gravity="center"
    android:text="聊天"
    android:textColor="#333"
    android:textSize="10sp" />
    <View
    android:layout_width="0dp"
    android:layout_height="1dp"
    android:layout_weight="1" />
    <Button
    android:id="@+id/btn_gift01"
    android:layout_width="40dp"
    android:layout_height="70dp"
    android:layout_marginRight="5dp"
    android:gravity="center"
    android:text="送香皂"
    android:textColor="#333"
    android:textSize="12sp" />
    <Button
    android:id="@+id/btn_gift02"
    android:layout_width="40dp"
    android:layout_height="70dp"
    android:layout_marginRight="5dp"
    android:gravity="center"
    android:text="送玫瑰"
    android:textColor="#333"
    android:textSize="12sp" />
    <Button
    android:id="@+id/btn_gift03"
    android:layout_width="40dp"
    android:layout_height="70dp"
    android:layout_marginRight="5dp"
    android:gravity="center"
    android:text="送爱心"
    android:textColor="#333"
    android:textSize="12sp" />
    <Button
    android:id="@+id/btn_gift04"
    android:layout_width="40dp"
    android:layout_height="70dp"
    android:layout_marginRight="5dp"
    android:gravity="center"
    android:text="送蛋糕"
    android:textColor="#333"
    android:textSize="12sp" />
    </LinearLayout>
    <LinearLayout
    android:id="@+id/ll_inputparent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="5dp"
    android:background="@android:color/white"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:visibility="gone">
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="horizontal">
    <EditText
    android:id="@+id/et_chat"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:background="@android:color/white"
    android:hint="在此输入你要说的话!"
    android:maxLength="30"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:textColor="#888889"
    android:textColorHint="#c8c8c8"
    android:textSize="12sp" />
    <TextView
    android:id="@+id/tv_send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:background="@android:color/holo_blue_bright"
    android:paddingLeft="10dp"
    android:paddingTop="5dp"
    android:paddingRight="10dp"
    android:paddingBottom="5dp"
    android:text="发送"
    android:textColor="@android:color/white"
    android:textSize="12sp" />
    </LinearLayout>
    </LinearLayout>
    </FrameLayout>
    </RelativeLayout>

    EmptyFrag:


    /**
    * 空的fragment
    */
    public class EmptyFrag extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.frag_empty, null);
    }
    }

    frag_empty.xml:


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:orientation="vertical">
    </LinearLayout>

    在MainActivity中使用FrameLayout布局,将观众功能交互页面 InteractiveFrag 覆盖在 直播页面LiveFrag上面。

    MainActivity:


    public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 加载直播fragment
    LiveFrag liveFrag = new LiveFrag();
    getSupportFragmentManager().beginTransaction().add(R.id.fl_root, liveFrag).commit();
    // 加载
    new InteractiveFrag().show(getSupportFragmentManager(), "InteractiveFrag");
    }
    }

    activity_main.xml :


    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
    android:id="@+id/fl_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </RelativeLayout>

    用户交互页实现

    MagicTextView动画效果

    MagicTextView代码在文章最后展示。

    我们先实现如下动画效果

    Android仿直播类app赠送礼物功能


    <com.hongx.zhibo.utils.MagicTextView
    android:id="@+id/mtv_giftNum"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginLeft="5dp"
    android:layout_toRightOf="@+id/rlparent"
    android:includeFontPadding="false"
    android:text="x1"
    android:textColor="@android:color/holo_red_dark"
    android:textSize="30sp"
    android:textStyle="bold"
    app:strokeColor="@android:color/white"
    app:strokeJoinStyle="miter"
    app:strokeWidth="2" />

    动画:


    public class NumberAnim {
    private Animator lastAnimator;
    public void showAnimator(View v) {
    if (lastAnimator != null) {
    lastAnimator.removeAllListeners();
    lastAnimator.cancel();
    lastAnimator.end();
    }
    ObjectAnimator animScaleX = ObjectAnimator.ofFloat(v, "scaleX", 1.3f, 1.0f);
    ObjectAnimator animScaleY = ObjectAnimator.ofFloat(v, "scaleY", 1.3f, 1.0f);
    AnimatorSet animSet = new AnimatorSet();
    animSet.playTogether(animScaleX, animScaleY);
    animSet.setDuration(200);
    lastAnimator = animSet;
    animSet.start();
    }
    }

    mtv_giftNum.setText("x" + count);
    giftNumberAnim = new NumberAnim(); // 初始化数字动画
    mtv_giftNum.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    count++;
    mtv_giftNum.setText("x" + count);
    giftNumberAnim.showAnimator(mtv_giftNum);
    }
    });

    礼物进入时动画

    Android仿直播类app赠送礼物功能

    进入动画设置为decelerate_interpolator减速插值器:


    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="-100%p"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:toYDelta="0%p">
    </translate>

    /**
    * 刷礼物的方法
    */
    private void showGift(String tag) {
    View newGiftView = ll_gift_group.findViewWithTag(tag);
    // 是否有该tag类型的礼物
    if (newGiftView == null) {
    // 获取礼物
    newGiftView = getNewGiftView(tag);
    ll_gift_group.addView(newGiftView);

    // 播放动画
    newGiftView.startAnimation(inAnim);
    final MagicTextView mtv_giftNum = newGiftView.findViewById(R.id.mtv_giftNum);
    inAnim.setAnimationListener(new Animation.AnimationListener() {

    @Override
    public void onAnimationStart(Animation animation) {
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
    giftNumberAnim.showAnimator(mtv_giftNum);
    }
    });
    } else {
    // 如果列表中已经有了该类型的礼物,则不再新建,直接拿出
    // 更新标识,记录最新修改的时间,用于回收判断
    ImageView iv_gift = newGiftView.findViewById(R.id.iv_gift);
    iv_gift.setTag(System.currentTimeMillis());

    // 更新标识,更新记录礼物个数
    MagicTextView mtv_giftNum = newGiftView.findViewById(R.id.mtv_giftNum);
    int giftCount = (int) mtv_giftNum.getTag() + 1; // 递增
    mtv_giftNum.setText("x" + giftCount);
    mtv_giftNum.setTag(giftCount);
    giftNumberAnim.showAnimator(mtv_giftNum);
    }
    }

    /**
    * 获取礼物
    */
    private View getNewGiftView(String tag) {

    // 添加标识, 该view若在layout中存在,就不在生成(用于findViewWithTag判断是否存在)
    View giftView = LayoutInflater.from(myContext).inflate(R.layout.item_gift, null);
    giftView.setTag(tag);

    // 添加标识, 记录生成时间,回收时用于判断是否是最新的,回收最老的
    ImageView iv_gift = giftView.findViewById(R.id.iv_gift);
    iv_gift.setTag(System.currentTimeMillis());

    // 添加标识,记录礼物个数
    MagicTextView mtv_giftNum = giftView.findViewById(R.id.mtv_giftNum);
    mtv_giftNum.setTag(1);
    mtv_giftNum.setText("x1");

    switch (tag) {
    case "gift01":
    iv_gift.setImageResource(GiftIcon[0]);
    break;
    case "gift02":
    iv_gift.setImageResource(GiftIcon[1]);
    break;
    case "gift03":
    iv_gift.setImageResource(GiftIcon[2]);
    break;
    case "gift04":
    iv_gift.setImageResource(GiftIcon[3]);
    break;
    }

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    lp.topMargin = 10;
    giftView.setLayoutParams(lp);

    return giftView;
    }

    @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_gift01: // 礼物1,送香皂
    showGift("gift01");
    break;
    case R.id.btn_gift02: // 礼物2,送玫瑰
    showGift("gift02");
    break;
    case R.id.btn_gift03: // 礼物3,送爱心
    showGift("gift03");
    break;
    case R.id.btn_gift04: // 礼物4,送蛋糕
    showGift("gift04");
    break;
    }
    }

    礼物移出动画

    实现的效果如下:

    Android仿直播类app赠送礼物功能

    礼物移出时使用accelerate_interpolator加速差值器


    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="0%p"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toYDelta="-100%p">
    </translate>

    /**
    * 移除礼物列表里的giftView
    */
    private void removeGiftView(final int index) {
    // 移除列表,外加退出动画
    final View removeGiftView = ll_gift_group.getChildAt(index);
    outAnim.setAnimationListener(new Animation.AnimationListener() {

    @Override
    public void onAnimationStart(Animation animation) {
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
    ll_gift_group.removeViewAt(index);
    }
    });

    // 开启动画,因为定时原因,所以可能是在子线程
    getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
    removeGiftView.startAnimation(outAnim);
    }
    });
    }

    如果显示的礼物大于3种,就将最早的那种礼物移除:


    // 是否有该tag类型的礼物
    if (newGiftView == null) {
    // 判断礼物列表是否已经有3个了,如果有那么删除掉一个没更新过的, 然后再添加新进来的礼物,始终保持只有3个
    if (ll_gift_group.getChildCount() >= 3) {
    // 获取前2个元素的最后更新时间
    View giftView01 = ll_gift_group.getChildAt(0);
    ImageView iv_gift01 = giftView01.findViewById(R.id.iv_gift);
    long lastTime1 = (long) iv_gift01.getTag();

    View giftView02 = ll_gift_group.getChildAt(1);
    ImageView iv_gift02 = giftView02.findViewById(R.id.iv_gift);
    long lastTime2 = (long) iv_gift02.getTag();

    if (lastTime1 > lastTime2) { // 如果第二个View显示的时间比较长
    removeGiftView(1);
    } else { // 如果第一个View显示的时间长
    removeGiftView(0);
    }
    }
    ...

    开启定时清理礼物列表

    礼物显示超过一定时间,自动将礼物在礼物列表中移除:


    /**
    * 定时清理礼物列表信息
    */
    private void clearTiming() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {

    @Override
    public void run() {
    int childCount = ll_gift_group.getChildCount();
    long nowTime = System.currentTimeMillis();
    for (int i = 0; i < childCount; i++) {

    View childView = ll_gift_group.getChildAt(i);
    ImageView iv_gift = (ImageView) childView.findViewById(R.id.iv_gift);
    long lastUpdateTime = (long) iv_gift.getTag();

    // 更新超过3秒就刷新
    if (nowTime - lastUpdateTime >= 3000) {
    removeGiftView(i);
    }
    }
    }
    }, 0, 3000);
    }

    Android仿直播类app赠送礼物功能

    聊天实现

    Android仿直播类app赠送礼物功能


    case R.id.tv_chat:// 聊天
    tv_chat.setVisibility(View.GONE);
    ll_inputparent.setVisibility(View.VISIBLE);
    ll_inputparent.requestFocus(); // 获取焦点
    showKeyboard();
    break;
    case R.id.tv_send:// 发送消息
    String chatMsg = et_chat.getText().toString();
    if (!TextUtils.isEmpty(chatMsg)) {
    messageData.add("小明: " + chatMsg);
    et_chat.setText("");
    messageAdapter.NotifyAdapter(messageData);
    lv_message.setSelection(messageData.size());
    }
    hideKeyboard();
    break;

    /**
    * 显示软键盘
    */
    private void showKeyboard() {
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.showSoftInput(et_chat, InputMethodManager.SHOW_FORCED);
    }

    /**
    * 隐藏软键盘
    */
    public void hideKeyboard() {
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(et_chat.getWindowToken(), 0);
    }

    view.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
    if (ll_inputparent.getVisibility() == View.VISIBLE) {
    tv_chat.setVisibility(View.VISIBLE);
    ll_inputparent.setVisibility(View.GONE);
    hideKeyboard();
    }
    }
    });

    // 软键盘监听
    SoftKeyBoardListener.setListener(getActivity(), new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
    @Override
    public void keyBoardShow(int height) {/*软键盘显示:执行隐藏title动画,并修改listview高度和装载礼物容器的高度*/

    // 输入文字时的界面退出动画
    AnimatorSet animatorSetHide = new AnimatorSet();
    ObjectAnimator leftOutAnim = ObjectAnimator.ofFloat(rl_num, "translationX", 0, -rl_num.getWidth());
    ObjectAnimator topOutAnim = ObjectAnimator.ofFloat(ll_anchor, "translationY", 0, -ll_anchor.getHeight());
    animatorSetHide.playTogether(leftOutAnim, topOutAnim);
    animatorSetHide.setDuration(300);
    animatorSetHide.start();
    // 改变listview的高度
    dynamicChangeListviewH(90);
    dynamicChangeGiftParentH(true);
    }

    @Override
    public void keyBoardHide(int height) {/*软键盘隐藏:隐藏聊天输入框并显示聊天按钮,执行显示title动画,并修改listview高度和装载礼物容器的高度*/
    tv_chat.setVisibility(View.VISIBLE);
    ll_inputparent.setVisibility(View.GONE);
    // 输入文字时的界面进入时的动画
    AnimatorSet animatorSetShow = new AnimatorSet();
    ObjectAnimator leftInAnim = ObjectAnimator.ofFloat(rl_num, "translationX", -rl_num.getWidth(), 0);
    ObjectAnimator topInAnim = ObjectAnimator.ofFloat(ll_anchor, "translationY", -ll_anchor.getHeight(), 0);
    animatorSetShow.playTogether(leftInAnim, topInAnim);
    animatorSetShow.setDuration(300);
    animatorSetShow.start();

    // 改变listview的高度
    dynamicChangeListviewH(150);
    dynamicChangeGiftParentH(false);
    }
    });

    /**
    * 动态的修改listview的高度
    */
    private void dynamicChangeListviewH(int heightPX) {
    ViewGroup.LayoutParams layoutParams = lv_message.getLayoutParams();
    layoutParams.height = DisplayUtil.dip2px(getActivity(), heightPX);
    lv_message.setLayoutParams(layoutParams);
    }

    /**
    * 动态修改礼物父布局的高度
    */
    private void dynamicChangeGiftParentH(boolean showhide) {
    if (showhide) {// 如果软键盘显示中
    if (ll_gift_group.getChildCount() != 0) {

    // 判断是否有礼物显示,如果有就修改父布局高度,如果没有就不作任何操作
    ViewGroup.LayoutParams layoutParams = ll_gift_group.getLayoutParams();
    layoutParams.height = ll_gift_group.getChildAt(0).getHeight();
    ll_gift_group.setLayoutParams(layoutParams);
    }
    } else {
    // 如果软键盘隐藏中
    // 就将装载礼物的容器的高度设置为包裹内容
    ViewGroup.LayoutParams layoutParams = ll_gift_group.getLayoutParams();
    layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    ll_gift_group.setLayoutParams(layoutParams);
    }
    }

    MagicTextView代码


    /**
    * 该自定义view是用于显示礼物数字的,加了些效果,内发光,阴影等
    */
    public class MagicTextView extends TextView {
    private ArrayList<Shadow> outerShadows;
    private ArrayList<Shadow> innerShadows;
    private WeakHashMap<String, Pair<Canvas, Bitmap>> canvasStore;
    private Canvas tempCanvas;
    private Bitmap tempBitmap;
    private Drawable foregroundDrawable;
    private float strokeWidth;
    private Integer strokeColor;
    private Join strokeJoin;
    private float strokeMiter;
    private int[] lockedCompoundPadding;
    private boolean frozen = false;
    public MagicTextView(Context context) {
    super(context);
    init(null);
    }
    public MagicTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs);
    }
    public MagicTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(attrs);
    }
    public void init(AttributeSet attrs) {
    outerShadows = new ArrayList<Shadow>();
    innerShadows = new ArrayList<Shadow>();
    if (canvasStore == null) {
    canvasStore = new WeakHashMap<String, Pair<Canvas, Bitmap>>();
    }
    if (attrs != null) {
    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MagicTextView);
    String typefaceName = a.getString(R.styleable.MagicTextView_typeface);
    if (typefaceName != null) {
    Typeface tf = Typeface.createFromAsset(getContext().getAssets(), String.format("fonts/%s.ttf", typefaceName));
    setTypeface(tf);
    }
    if (a.hasValue(R.styleable.MagicTextView_foreground)) {
    Drawable foreground = a.getDrawable(R.styleable.MagicTextView_foreground);
    if (foreground != null) {
    this.setForegroundDrawable(foreground);
    } else {
    this.setTextColor(a.getColor(R.styleable.MagicTextView_foreground, 0xff000000));
    }
    }
    if (a.hasValue(R.styleable.MagicTextView_innerShadowColor)) {
    this.addInnerShadow(a.getFloat(R.styleable.MagicTextView_innerShadowRadius, 0),
    a.getFloat(R.styleable.MagicTextView_innerShadowDx, 0),
    a.getFloat(R.styleable.MagicTextView_innerShadowDy, 0),
    a.getColor(R.styleable.MagicTextView_innerShadowColor, 0xff000000));
    }
    if (a.hasValue(R.styleable.MagicTextView_outerShadowColor)) {
    this.addOuterShadow(a.getFloat(R.styleable.MagicTextView_outerShadowRadius, 0),
    a.getFloat(R.styleable.MagicTextView_outerShadowDx, 0),
    a.getFloat(R.styleable.MagicTextView_outerShadowDy, 0),
    a.getColor(R.styleable.MagicTextView_outerShadowColor, 0xff000000));
    }
    if (a.hasValue(R.styleable.MagicTextView_strokeColor)) {
    float strokeWidth = a.getFloat(R.styleable.MagicTextView_strokeWidth, 1);
    int strokeColor = a.getColor(R.styleable.MagicTextView_strokeColor, 0xff000000);
    float strokeMiter = a.getFloat(R.styleable.MagicTextView_strokeMiter, 10);
    Join strokeJoin = null;
    switch (a.getInt(R.styleable.MagicTextView_strokeJoinStyle, 0)) {
    case (0):
    strokeJoin = Join.MITER;
    break;
    case (1):
    strokeJoin = Join.BEVEL;
    break;
    case (2):
    strokeJoin = Join.ROUND;
    break;
    }
    this.setStroke(strokeWidth, strokeColor, strokeJoin, strokeMiter);
    }
    }
    }
    public void setStroke(float width, int color, Join join, float miter) {
    strokeWidth = width;
    strokeColor = color;
    strokeJoin = join;
    strokeMiter = miter;
    }
    public void setStroke(float width, int color) {
    setStroke(width, color, Join.MITER, 10);
    }
    public void addOuterShadow(float r, float dx, float dy, int color) {
    if (r == 0) {
    r = 0.0001f;
    }
    outerShadows.add(new Shadow(r, dx, dy, color));
    }
    public void addInnerShadow(float r, float dx, float dy, int color) {
    if (r == 0) {
    r = 0.0001f;
    }
    innerShadows.add(new Shadow(r, dx, dy, color));
    }
    public void clearInnerShadows() {
    innerShadows.clear();
    }
    public void clearOuterShadows() {
    outerShadows.clear();
    }
    public void setForegroundDrawable(Drawable d) {
    this.foregroundDrawable = d;
    }
    public Drawable getForeground() {
    return this.foregroundDrawable == null ? this.foregroundDrawable : new ColorDrawable(this.getCurrentTextColor());
    }
    @Override
    public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    freeze();
    Drawable restoreBackground = this.getBackground();
    Drawable[] restoreDrawables = this.getCompoundDrawables();
    int restoreColor = this.getCurrentTextColor();
    this.setCompoundDrawables(null, null, null, null);
    for (Shadow shadow : outerShadows) {
    this.setShadowLayer(shadow.r, shadow.dx, shadow.dy, shadow.color);
    super.onDraw(canvas);
    }
    this.setShadowLayer(0, 0, 0, 0);
    this.setTextColor(restoreColor);
    if (this.foregroundDrawable != null && this.foregroundDrawable instanceof BitmapDrawable) {
    generateTempCanvas();
    super.onDraw(tempCanvas);
    Paint paint = ((BitmapDrawable) this.foregroundDrawable).getPaint();
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
    this.foregroundDrawable.setBounds(canvas.getClipBounds());
    this.foregroundDrawable.draw(tempCanvas);
    canvas.drawBitmap(tempBitmap, 0, 0, null);
    tempCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    }
    if (strokeColor != null) {
    TextPaint paint = this.getPaint();
    // paint.setTextAlign(Paint.Align.CENTER);
    paint.setStyle(Style.STROKE);
    paint.setStrokeJoin(strokeJoin);
    paint.setStrokeMiter(strokeMiter);
    this.setTextColor(strokeColor);
    paint.setStrokeWidth(strokeWidth);
    super.onDraw(canvas);
    paint.setStyle(Style.FILL);
    this.setTextColor(restoreColor);
    }
    if (innerShadows.size() > 0) {
    generateTempCanvas();
    TextPaint paint = this.getPaint();
    for (Shadow shadow : innerShadows) {
    this.setTextColor(shadow.color);
    super.onDraw(tempCanvas);
    this.setTextColor(0xFF000000);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    paint.setMaskFilter(new BlurMaskFilter(shadow.r, BlurMaskFilter.Blur.NORMAL));
    tempCanvas.save();
    tempCanvas.translate(shadow.dx, shadow.dy);
    super.onDraw(tempCanvas);
    tempCanvas.restore();
    canvas.drawBitmap(tempBitmap, 0, 0, null);
    tempCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    paint.setXfermode(null);
    paint.setMaskFilter(null);
    this.setTextColor(restoreColor);
    this.setShadowLayer(0, 0, 0, 0);
    }
    }
    if (restoreDrawables != null) {
    this.setCompoundDrawablesWithIntrinsicBounds(restoreDrawables[0], restoreDrawables[1], restoreDrawables[2], restoreDrawables[3]);
    }
    this.setBackgroundDrawable(restoreBackground);
    this.setTextColor(restoreColor);
    unfreeze();
    }
    private void generateTempCanvas() {
    String key = String.format("%dx%d", getWidth(), getHeight());
    Pair<Canvas, Bitmap> stored = canvasStore.get(key);
    if (stored != null) {
    tempCanvas = stored.first;
    tempBitmap = stored.second;
    } else {
    tempCanvas = new Canvas();
    tempBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    tempCanvas.setBitmap(tempBitmap);
    canvasStore.put(key, new Pair<Canvas, Bitmap>(tempCanvas, tempBitmap));
    }
    }
    public void freeze() {
    lockedCompoundPadding = new int[]{
    getCompoundPaddingLeft(),
    getCompoundPaddingRight(),
    getCompoundPaddingTop(),
    getCompoundPaddingBottom()
    };
    frozen = true;
    }
    public void unfreeze() {
    frozen = false;
    }
    @Override
    public void requestLayout() {
    if (!frozen) super.requestLayout();
    }
    @Override
    public void postInvalidate() {
    if (!frozen) super.postInvalidate();
    }
    @Override
    public void postInvalidate(int left, int top, int right, int bottom) {
    if (!frozen) super.postInvalidate(left, top, right, bottom);
    }
    @Override
    public void invalidate() {
    if (!frozen) super.invalidate();
    }
    @Override
    public void invalidate(Rect rect) {
    if (!frozen) super.invalidate(rect);
    }
    @Override
    public void invalidate(int l, int t, int r, int b) {
    if (!frozen) super.invalidate(l, t, r, b);
    }
    @Override
    public int getCompoundPaddingLeft() {
    return !frozen ? super.getCompoundPaddingLeft() : lockedCompoundPadding[0];
    }
    @Override
    public int getCompoundPaddingRight() {
    return !frozen ? super.getCompoundPaddingRight() : lockedCompoundPadding[1];
    }
    @Override
    public int getCompoundPaddingTop() {
    return !frozen ? super.getCompoundPaddingTop() : lockedCompoundPadding[2];
    }
    @Override
    public int getCompoundPaddingBottom() {
    return !frozen ? super.getCompoundPaddingBottom() : lockedCompoundPadding[3];
    }
    public static class Shadow {
    float r;
    float dx;
    float dy;
    int color;

    public Shadow(float r, float dx, float dy, int color) {
    this.r = r;
    this.dx = dx;
    this.dy = dy;
    this.color = color;
    }
    }
    }

    Github:https://github.com/345166018/AndroidUI/tree/master/HxZhibo

    总结

    以上所述是小编给大家介绍的Android仿直播类app赠送礼物功能,希望对大家有所帮助!

    来源:https://blog.csdn.net/hongxue8888/article/details/104135163

    0
    投稿

    猜你喜欢

    手机版 软件编程 asp之家 www.aspxhome.com