溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android如何實現(xiàn)仿直播類app贈送禮物功能

發(fā)布時間:2021-06-28 09:15:43 來源:億速云 閱讀:156 作者:小新 欄目:移動開發(fā)

這篇文章給大家分享的是有關(guān)Android如何實現(xiàn)仿直播類app贈送禮物功能的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

實現(xiàn)的是播放本地的視頻文件:

/**
 * 直播界面,用于對接直播功能
 */
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>

滑動隱藏效果

需要實現(xiàn)的效果如下:

Android如何實現(xiàn)仿直播類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);
 }

 /**
 * 初始化數(shù)據(jù)
 */
 public void initData() {
 // EmptyFrag:什么都沒有
 // LayerFrag:交互界面
 // 這樣就達(dá)到了滑動隱藏交互的需求
 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 { // 設(shè)置默認(rèn)

 return new EmptyFrag();
 }
 }
 });
 // 設(shè)置默認(rèn)顯示交互界面
 vp_interactive.setCurrentItem(1);

 // 同時將界面改為resize已達(dá)到軟鍵盤彈出時Fragment不會跟隨移動
 getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
 }

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {

 // 設(shè)置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="發(fā)送"
 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>

用戶交互頁實現(xiàn)

MagicTextView動畫效果

MagicTextView代碼在文章最后展示。

我們先實現(xiàn)如下動畫效果

Android如何實現(xiàn)仿直播類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(); // 初始化數(shù)字動畫 
 mtv_giftNum.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 count++;
 mtv_giftNum.setText("x" + count);
 giftNumberAnim.showAnimator(mtv_giftNum);
 }
 });

禮物進(jìn)入時動畫

Android如何實現(xiàn)仿直播類app贈送禮物功能

進(jìn)入動畫設(shè)置為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 {
 // 如果列表中已經(jīng)有了該類型的禮物,則不再新建,直接拿出
 // 更新標(biāo)識,記錄最新修改的時間,用于回收判斷
 ImageView iv_gift = newGiftView.findViewById(R.id.iv_gift);
 iv_gift.setTag(System.currentTimeMillis());

 // 更新標(biāo)識,更新記錄禮物個數(shù)
 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) {

 // 添加標(biāo)識, 該view若在layout中存在,就不在生成(用于findViewWithTag判斷是否存在)
 View giftView = LayoutInflater.from(myContext).inflate(R.layout.item_gift, null);
 giftView.setTag(tag);

 // 添加標(biāo)識, 記錄生成時間,回收時用于判斷是否是最新的,回收最老的
 ImageView iv_gift = giftView.findViewById(R.id.iv_gift);
 iv_gift.setTag(System.currentTimeMillis());

 // 添加標(biāo)識,記錄禮物個數(shù)
 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;
 }
 }

禮物移出動畫

實現(xiàn)的效果如下:

Android如何實現(xiàn)仿直播類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) {
 // 判斷禮物列表是否已經(jīng)有3個了,如果有那么刪除掉一個沒更新過的, 然后再添加新進(jìn)來的禮物,始終保持只有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如何實現(xiàn)仿直播類app贈送禮物功能

聊天實現(xiàn)

Android如何實現(xiàn)仿直播類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:// 發(fā)送消息
 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();
 }
 }
 });

 // 軟鍵盤監(jiān)聽
 SoftKeyBoardListener.setListener(getActivity(), new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
 @Override
 public void keyBoardShow(int height) {/*軟鍵盤顯示:執(zhí)行隱藏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) {/*軟鍵盤隱藏:隱藏聊天輸入框并顯示聊天按鈕,執(zhí)行顯示title動畫,并修改listview高度和裝載禮物容器的高度*/
 tv_chat.setVisibility(View.VISIBLE);
 ll_inputparent.setVisibility(View.GONE);
 // 輸入文字時的界面進(jìn)入時的動畫
 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);
 }
 });

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

 /**
 * 動態(tài)修改禮物父布局的高度
 */
 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 {
 // 如果軟鍵盤隱藏中
 // 就將裝載禮物的容器的高度設(shè)置為包裹內(nèi)容
 ViewGroup.LayoutParams layoutParams = ll_gift_group.getLayoutParams();
 layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
 ll_gift_group.setLayoutParams(layoutParams);
 }
 }

MagicTextView代碼

/**
 * 該自定義view是用于顯示禮物數(shù)字的,加了些效果,內(nèi)發(fā)光,陰影等
 */
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;
 }
 }
}

感謝各位的閱讀!關(guān)于“Android如何實現(xiàn)仿直播類app贈送禮物功能”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI