日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android仿直播特效之刷礼物

發布時間:2024/1/1 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android仿直播特效之刷礼物 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述

繼續咱們的直播之旅,過段時間再把推流拉流寫上博客,暫時還是UI特效,先上圖


二、創建我們的BaseActivity和BaseFrag

/*** @author 劉洋巴金* @date 2017-5-3* * 基類* */ public abstract class BaseActivity extends FragmentActivity implements OnClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(getLayoutId());initBase();initView();initData();initListener();}/*** 設置子類getLayoutId* */public abstract int getLayoutId();/*** 基類初始化* */public void initBase() {}/*** 子類初始化View* */public void initView() {}/*** 子類初始化數據* */public void initData() {}/*** 子類初始化監聽* */public void initListener() {}@Overridepublic void onClick(View v) {} }

baseFrag

/*** @author 劉洋巴金* @date 2017-5-3* * Frag基類* */ public abstract class BaseFrag extends Fragment implements OnClickListener{public View view;public Context myContext;@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {view = inflater.inflate(getLayoutId(), null);// 初始化initBase();initView();initData();initListener();return view;}/*** 設置子類getLayoutId* */public abstract int getLayoutId();/*** 基類初始化* */public void initBase() {myContext = getActivity();}/*** 子類初始化View* */public void initView() {}/*** 子類初始化數據* */public void initData() {}/*** 子類初始化監聽* */public void initListener() {}@Overridepublic void onClick(View v) {} } 和baseActivity差不多

這個就是我們的基類,然后是我們的主類

/*** @author 劉洋巴金* @date 2017-5-3* * 主頁* */ public class MainActivity extends BaseActivity {@Overridepublic int getLayoutId() {return R.layout.activity_main;}@Overridepublic void initData() {super.initData();// 加載直播fragmentLiveFrag liveFrag = new LiveFrag();getSupportFragmentManager().beginTransaction().add(R.id.fl_root, liveFrag).commit();// 加載new InteractiveFrag().show(getSupportFragmentManager(), "InteractiveFrag");} }經過封裝簡單了很多吧?然后是加載fragment,LiveFrag就是我們的直播frag,現在目前為止就是一個圖片,以后增加拉流等相關功能,然后加載我們的用戶交互InteractiveFrag。

它是繼承DialogFragment,這個不明白的可以百度查詢,而這個也不是必須,可以自定義,

這里最主要的邏輯就是加了一個viewpager, 共加載了2個fragment,一個是我們交互用的,一個是透明的,這樣是為了滑動隱藏我們的交互的功能,如上圖最后的操作。EmptyFrag背景設置為透明,無任何邏輯

/*** 觀眾功能交互頁面, 滑動隱藏效果* * @author 劉洋巴金* @date 2017-5-3*/ public class InteractiveFrag extends DialogFragment{public View view;public Context myContext;private ViewPager vp_interactive;private LayerFrag layerFrag;@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {view = inflater.inflate(R.layout.frag_interactive, null);// 初始化initView();initData();initListener();return view;}/*** 初始化View* */public void initView() {vp_interactive = (ViewPager)view.findViewById(R.id.vp_interactive);}/*** 初始化數據* */public void initData() {// EmptyFrag:什么都沒有// LayerFrag:交互界面// 這樣就達到了滑動隱藏交互的需求vp_interactive.setAdapter(new FragmentPagerAdapter(getChildFragmentManager()) {@Overridepublic int getCount() {return 2;}@Overridepublic 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);}/*** 初始化監聽* */public void initListener() {vp_interactive.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {if(position == 0){// layerFrag.hideKeyboard();}}@Overridepublic void onPageScrolled(int position, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int position) {}});}@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {// 設置DialogFragment的樣式,這里的代碼最好還是用我的,大家不要改動Dialog dialog = new Dialog(getActivity(), R.style.MainDialog){@Overridepublic void onBackPressed() {super.onBackPressed();getActivity().finish();}};return dialog;} } 三、實現我們的交互頁面

/*** 用戶交互頁* * @author 劉洋巴金* @date 2017-5-3*/ public class LayerFrag extends BaseFrag{private NumberAnim giftNumberAnim;private List<String> messageData = new LinkedList<>();private MessageAdapter messageAdapter;private ListView lv_message;private HorizontalListView hlv_audience;private LinearLayout ll_gift_group;private TranslateAnimation outAnim;private TranslateAnimation inAnim;private LinearLayout ll_inputparent;private Button tv_chat;private EditText et_chat;private LinearLayout ll_anchor;private RelativeLayout rl_num;@Overridepublic int getLayoutId() {// TODO Auto-generated method stubreturn R.layout.frag_layer;}@Overridepublic void initView() {// TODO Auto-generated method stubsuper.initView();lv_message = (ListView)view.findViewById(R.id.lv_message);hlv_audience = (HorizontalListView)view.findViewById(R.id.hlv_audience);ll_gift_group = (LinearLayout)view.findViewById(R.id.ll_gift_group);ll_inputparent = (LinearLayout)view.findViewById(R.id.ll_inputparent);tv_chat = (Button)view.findViewById(R.id.tv_chat);et_chat = (EditText)view.findViewById(R.id.et_chat);ll_anchor = (LinearLayout)view.findViewById(R.id.ll_anchor);rl_num = (RelativeLayout)view.findViewById(R.id.rl_num);}@Overridepublic void initData() {// TODO Auto-generated method stubsuper.initData();initAudience(); // 初始化觀眾initMessage(); // 初始化評論clearTiming(); // 開啟定時清理禮物列表initAnim(); // 初始化動畫} 進行初始化和變量聲明,首先初始化右上角的觀眾,其實就是個GridView,這里不再概述

/*** 初始化觀眾列表* */ private void initAudience() {hlv_audience.setAdapter(new AudienceAdapter(myContext)); }然后初始化評論,左下角底部的評論列表,listview不再概述

/*** 初始化評論列表* */ private void initMessage() {for(int x = 0; x < 20; x++){messageData.add("劉洋巴金: 主播好漂亮啊" + x);}messageAdapter = new MessageAdapter(getActivity(), messageData);lv_message.setAdapter(messageAdapter);lv_message.setSelection(messageData.size()); }初始化動畫

/*** 初始化動畫* */ private void initAnim() {giftNumberAnim = new NumberAnim(); // 初始化數字動畫inAnim = (TranslateAnimation) AnimationUtils.loadAnimation(getActivity(), R.anim.gift_in); // 禮物進入時動畫outAnim = (TranslateAnimation) AnimationUtils.loadAnimation(getActivity(), R.anim.gift_out); // 禮物退出時動畫 }

禮物的數字動畫,就是簡單的放大

/*** 送的禮物后面的數字動畫* */ 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();} }設置禮物的動畫集合,使它放大1.3倍

clearTiming為禮物清理,3秒后自動清理,這個放在后面講,先開始刷禮物

@Override public void onClick(View v) {// TODO Auto-generated method stubsuper.onClick(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;4個按鈕的點擊事件

然后是刷禮物

/*** 刷禮物* */ private void showGift(String tag) {View newGiftView = ll_gift_group.findViewWithTag(tag);// 是否有該tag類型的禮物if(newGiftView == null){// 判斷禮物列表是否已經有3個了,如果有那么刪除掉一個沒更新過的, 然后再添加新進來的禮物,始終保持只有3個if(ll_gift_group.getChildCount() >= 3){// 獲取前2個元素的最后更新時間View giftView01 = ll_gift_group.getChildAt(0);ImageView iv_gift01 = (ImageView)giftView01.findViewById(R.id.iv_gift);long lastTime1 = (long) iv_gift01.getTag();View giftView02 = ll_gift_group.getChildAt(1);ImageView iv_gift02 = (ImageView)giftView02.findViewById(R.id.iv_gift);long lastTime2 = (long) iv_gift02.getTag();if (lastTime1 > lastTime2) { // 如果第二個View顯示的時間比較長removeGiftView(1);} else { // 如果第一個View顯示的時間長removeGiftView(0);}}// 獲取禮物newGiftView = getNewGiftView(tag);ll_gift_group.addView(newGiftView);// 播放動畫newGiftView.startAnimation(inAnim);final MagicTextView mtv_giftNum = (MagicTextView) newGiftView.findViewById(R.id.mtv_giftNum);inAnim.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {// TODO Auto-generated method stubgiftNumberAnim.showAnimator(mtv_giftNum);}});}else{...} }1.這段是核心代碼,首先評論去上方我們定義了一個LinearLayout,ll_gift_group,
2.然后根據點擊事件傳入tag,在 ll_gift_group查詢是否有該tag的子控件,也就是是否有該種類的禮物,如果沒有,判斷當前不同種類是否已經3個了,如果是,那么移除一個最先更新的禮物。

3.位置空出來了,生成我們的禮物

/*** 獲取禮物* */ 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 = (ImageView)giftView.findViewById(R.id.iv_gift);iv_gift.setTag(System.currentTimeMillis());// 添加標識,記錄禮物個數MagicTextView mtv_giftNum = (MagicTextView) 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; }1.生成我們的禮物控件,然后綁定tag進行標識,就是點擊事件傳遞過來的tag,

2.找其子控件,再綁定更新時間,因為要回收更新最早的控件,保留最后更新的

3.找其子控件,添加標識,記錄該種禮物的個數

4.設置禮物圖片

5.設置大小返回

好繼續回到我們的showGift方法

4.生成禮物后,添加到 ll_gift_group中,并執行進入動畫,MagicTextView為我們自定義的禮物數量的字體樣式,這個沒有規定可隨意自定義

5.禮物進入動畫執行完畢后,再執行數字動畫,就是放大

好了,然后我們又刷了一個禮物。

根據

View newGiftView = ll_gift_group.findViewWithTag(tag);判讀是否該類型的禮物還沒有被清理掉

如果是,那么我們走else

View newGiftView = ll_gift_group.findViewWithTag(tag);// 是否有該tag類型的禮物 if(newGiftView == null){... }else{// 如果列表中已經有了該類型的禮物,則不再新建,直接拿出// 更新標識,記錄最新修改的時間,用于回收判斷ImageView iv_gift = (ImageView)newGiftView.findViewById(R.id.iv_gift);iv_gift.setTag(System.currentTimeMillis());// 更新標識,更新記錄禮物個數MagicTextView mtv_giftNum = (MagicTextView) 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); }1.首先拿出禮物控件的子控件,更新它的更新時間

2.然后再拿出其子控件更新他的禮物數量的標識。

3.更改UI,執行數字動畫

這樣禮物就刷出去了,但是為了用戶體驗,禮物要3秒鐘之后消失

/*** 定時清理禮物列表信息*/ private void clearTiming() {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic 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); }這個就比較簡單了,拿出?ll_gift_group中全部的控件,遍歷他們,取出他們最后更新的時間,然后對比當前時間,如果誰的時間超過3秒了,那么執行移除

/*** 移除禮物列表里的giftView* */ private void removeGiftView(final int index) {// 移除列表,外加退出動畫final View removeGiftView = ll_gift_group.getChildAt(index);outAnim.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {// TODO Auto-generated method stubll_gift_group.removeViewAt(index);}});// 開啟動畫,因為定時原因,所以可能是在子線程getActivity().runOnUiThread(new Runnable() {@Overridepublic void run() {removeGiftView.startAnimation(outAnim);}}); }移除禮物,然后執行退出動畫。

好了刷禮物就到這吧,不明白的話,底下評論

四、demo

Android仿直播特效之刷禮物

總結

以上是生活随笔為你收集整理的Android仿直播特效之刷礼物的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。