Merge remote-tracking branch 'origin/master'

This commit is contained in:
18142669586 2022-08-31 18:31:08 +08:00
commit 085b23a61d
9 changed files with 123 additions and 107 deletions

View File

@ -159,11 +159,11 @@ public class IMLoginManager extends BaseCacheManager {
} }
public boolean isMountEffect() { public boolean isMountEffect() {
return getBoolean(MountEffect, false); return getBoolean(MountEffect, true);
} }
public boolean isGiftEffect() { public boolean isGiftEffect() {
return getBoolean(GiftEffect, false); return getBoolean(GiftEffect, true);
} }
/** /**

View File

@ -216,6 +216,7 @@ public class LiveAudienceActivity extends LiveActivity {
public void onPageSelected(int position) { public void onPageSelected(int position) {
super.onPageSelected(position); super.onPageSelected(position);
mCurrentPage = position; mCurrentPage = position;
} }
}); });
verticalViewPager.setPageTransformer(false, new ViewPager.PageTransformer() { verticalViewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
@ -234,7 +235,6 @@ public class LiveAudienceActivity extends LiveActivity {
manager.onRemove(); manager.onRemove();
} }
} }
// 满足此种条件表明需要加载直播视频以及聊天室了 // 满足此种条件表明需要加载直播视频以及聊天室了
if (viewGroup.getId() == mCurrentItem && (position == 0) && mCurrentItem != mLastPosition) { if (viewGroup.getId() == mCurrentItem && (position == 0) && mCurrentItem != mLastPosition) {
loadData(viewGroup, mCurrentItem); loadData(viewGroup, mCurrentItem);
@ -249,20 +249,9 @@ public class LiveAudienceActivity extends LiveActivity {
private void loadData(ViewGroup viewGroup, int currentItem) { private void loadData(ViewGroup viewGroup, int currentItem) {
mViewGroup = viewGroup; mViewGroup = viewGroup;
mLastPosition = currentItem; mLastPosition = currentItem;
liveHandler.removeCallbacks(liveRunnable); liveHandler.post(liveRunnable);
if (mCurrentPage > 0) {
liveHandler.postDelayed(liveRunnable, 800);
} else {
liveHandler.post(liveRunnable);
}
Log.e("收到socket--->", "mLiveUid--------------------------->" + mLiveUid); Log.e("收到socket--->", "mLiveUid--------------------------->" + mLiveUid);
//加载当前页面数据
View rootView = manager.getRootView();
if (rootView.getParent() != null && rootView.getParent() instanceof ViewGroup) {
((ViewGroup) (rootView.getParent())).removeView(rootView);
manager.onRemove();
}
mViewGroup.addView(manager.getRootView());
} }
//获取直播间状态 //获取直播间状态
@ -292,17 +281,30 @@ public class LiveAudienceActivity extends LiveActivity {
if (liveBean1 == null) { if (liveBean1 == null) {
return; return;
} }
mLiveSDK = liveSdk; runOnUiThread(new Runnable() {
mLiveType = liveType; @Override
mLiveTypeVal = liveTypeVal; public void run() {
mLiveBean = liveBean1; mLiveSDK = liveSdk;
mLiveUid = liveBean1.getUid(); mLiveType = liveType;
mStream = liveBean1.getStream(); mLiveTypeVal = liveTypeVal;
mAncherName = liveBean1.getUserNiceName(); mLiveBean = liveBean1;
mAncherIcon = liveBean1.getAvatar(); mLiveUid = liveBean1.getUid();
mStream = liveBean1.getStream();
mAncherName = liveBean1.getUserNiceName();
mAncherIcon = liveBean1.getAvatar();
Log.e("收到socket--->", "mLiveUid--------------------------->" + mLiveUid);
//加载当前页面数据
View rootView = manager.getRootView();
if (rootView.getParent() != null && rootView.getParent() instanceof ViewGroup) {
((ViewGroup) (rootView.getParent())).removeView(rootView);
manager.onRemove();
}
mViewGroup.addView(manager.getRootView());
manager.onAdd(liveBean1, liveType, liveTypeVal, liveSdk);
}
});
manager.onAdd(liveBean1, liveType, liveTypeVal, liveSdk);
}); });

View File

@ -44,12 +44,13 @@ public class VerticalPagerAdapter extends androidx.viewpager.widget.PagerAdapter
@Override @Override
public Object instantiateItem(ViewGroup container, int position) { public Object instantiateItem(ViewGroup container, int position) {
Log.e("LiveAudienceActivity", "VerticalPagerAdapter:" + position);
View view = LayoutInflater.from(container.getContext()).inflate(R.layout.layout_portrait_live_item, null); View view = LayoutInflater.from(container.getContext()).inflate(R.layout.layout_portrait_live_item, null);
// 背景 // 背景
AnchorRecommendItemModel liveItemBean = liveBeans.get(position); AnchorRecommendItemModel liveItemBean = liveBeans.get(position);
ImageView ivBg = view.findViewById(R.id.iv_bg); ImageView ivBg = view.findViewById(R.id.iv_bg);
ImgLoader.displayBlurLive(mContext, liveItemBean.getAvatar(), ivBg); ImgLoader.displayBlurLive(mContext, liveItemBean.getAvatar(), ivBg);
Log.e("LiveAudienceActivity", "加载图片:" + liveItemBean.getAvatar());
// 加载动画 // 加载动画
ImageView ivLoading = view.findViewById(R.id.iv_loading); ImageView ivLoading = view.findViewById(R.id.iv_loading);
AnimationDrawable frameAnimation = (AnimationDrawable) ivLoading.getBackground(); AnimationDrawable frameAnimation = (AnimationDrawable) ivLoading.getBackground();

View File

@ -181,10 +181,7 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
private void ininView() { private void ininView() {
// 直播间根布局 // 直播间根布局
mRootContainer = (DrawerLayout) LayoutInflater.from(mContext).inflate(R.layout.activity_live_audience, null); mRootContainer = (DrawerLayout) LayoutInflater.from(mContext).inflate(R.layout.activity_live_audience, null);
playContainer = mRootContainer.findViewById(R.id.play_container); playContainer = mRootContainer.findViewById(R.id.play_container);
mViewPager = mRootContainer.findViewById(R.id.viewPager); mViewPager = mRootContainer.findViewById(R.id.viewPager);
btnSmallScreen = mRootContainer.findViewById(R.id.btn_small_screen); btnSmallScreen = mRootContainer.findViewById(R.id.btn_small_screen);
mSecondPage = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.view_audience_page, mViewPager, false); mSecondPage = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.view_audience_page, mViewPager, false);
@ -200,89 +197,104 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
mContainer.removeAllViews(); mContainer.removeAllViews();
mViewPager.setAdapter(pagerAdapter); mViewPager.setAdapter(pagerAdapter);
mViewPager.setCurrentItem(1); mViewPager.setCurrentItem(1);
//直播页面背景 //直播页面背景
liveBack = mRootContainer.findViewById(R.id.live_back); liveBack = mRootContainer.findViewById(R.id.live_back);
mask = mRootContainer.findViewById(R.id.mask); mask = mRootContainer.findViewById(R.id.mask);
} }
@Override @Override
public void onAdd(LiveBean data, int liveType, int liveTypeVal, int liveSdk) { public void onAdd(LiveBean data, int liveType, int liveTypeVal, int liveSdk) {
mLiveBean = data; mContext.runOnUiThread(new Runnable() {
mLiveSDK = liveSdk;
mLiveType = liveType;
mLiveTypeVal = liveTypeVal;
liveID = data.getUid();
Bus.get().post(new LiveAudienceEvent()
.setType(LiveAudienceEvent.LiveAudienceType.OPEN_PARAMETERS)
.setParametersModel(new OpenParametersModel()
.setmLiveType(mLiveType)
.setmLiveTypeVal(mLiveTypeVal)));
mLivePlayViewHolder = new LivePlayRyViewHolder(mContext, playContainer, mIntent.getIntExtra("landscape", 0));
mLivePlayViewHolder.addToParent();
mLivePlayViewHolder.subscribeActivityLifeCycle();
mLiveRoomViewHolder = new LiveRoomViewHolder(false, 1, mContext, mContainer, mSecondPage.findViewById(R.id.gift_gif), mSecondPage.findViewById(R.id.gift_svga), mContainerWrap, mContext.getWindowManager());
mLiveRoomViewHolder.subscribeActivityLifeCycle();
mLiveAudienceViewHolder = new LiveAudienceViewHolder(mContext, mContainer);
mLiveAudienceViewHolder.addToParent();
mLiveRoomViewHolder.addToParent();
mLiveAudienceViewHolder.subscribeActivityLifeCycle();
mLiveLinkMicPresenter = new LiveLinkMicPresenter(mContext, mLivePlayViewHolder, false, mLiveSDK, mLiveAudienceViewHolder.getContentView());
mLiveLinkMicAnchorPresenter = new LiveLinkMicAnchorPresenter(mContext, mLivePlayViewHolder, false, mLiveSDK, null);
mLiveRyLinkMicPkPresenter = new LiveRyLinkMicPkPresenter(mContext, mLivePlayViewHolder, false, null);
//直播间背景
ImgLoader.displayBlurLive(mContext, data.getAvatar(), liveBack);
mask.setVisibility(View.VISIBLE);
mLivePlayViewHolder.setCover(data.getThumb());
mLivePlayViewHolder.play(data.getPull());
mLiveRoomViewHolder.setAvatar(data.getAvatar());
mLiveRoomViewHolder.setAnchorLevel(data.getLevelAnchor());
mLiveRoomViewHolder.setName(data.getUserNiceName());
mLiveRoomViewHolder.setRoomNum(data.getLiangNameTip());
mLiveRoomViewHolder.setTitle(data.getTitle());
mLiveRyLinkMicPkPresenter.setLiveUid(data.getUid(), "");
mLiveRoomViewHolder.setLiveUid(data.getUid());
//心愿单
LiveHttpUtil.getWishList(mLiveBean.getUid(), new HttpCallback() {
@Override @Override
public void onSuccess(int code, String msg, String[] info) { public void run() {
if (info.length > 0) { Log.e("ImgLoader1", data.getAvatar());
String json = info[0];
WishlistModel model = GsonUtils.fromJson(json, WishlistModel.class);
if (mLiveRoomViewHolder != null && model != null) mLiveBean = data;
mLiveRoomViewHolder.initWishList(model.getWishlist()); mLiveSDK = liveSdk;
mLiveType = liveType;
mLiveTypeVal = liveTypeVal;
liveID = data.getUid();
Bus.get().post(new LiveAudienceEvent()
.setType(LiveAudienceEvent.LiveAudienceType.OPEN_PARAMETERS)
.setParametersModel(new OpenParametersModel()
.setmLiveType(mLiveType)
.setmLiveTypeVal(mLiveTypeVal)));
mLivePlayViewHolder = new LivePlayRyViewHolder(mContext, playContainer, mIntent.getIntExtra("landscape", 0));
mLivePlayViewHolder.addToParent();
mLivePlayViewHolder.subscribeActivityLifeCycle();
mLiveRoomViewHolder = new LiveRoomViewHolder(false, 1, mContext, mContainer, mSecondPage.findViewById(R.id.gift_gif), mSecondPage.findViewById(R.id.gift_svga), mContainerWrap, mContext.getWindowManager());
mLiveRoomViewHolder.subscribeActivityLifeCycle();
mLiveAudienceViewHolder = new LiveAudienceViewHolder(mContext, mContainer);
mLiveAudienceViewHolder.addToParent();
mLiveRoomViewHolder.addToParent();
mLiveAudienceViewHolder.subscribeActivityLifeCycle();
mLiveLinkMicPresenter = new LiveLinkMicPresenter(mContext, mLivePlayViewHolder, false, mLiveSDK, mLiveAudienceViewHolder.getContentView());
mLiveLinkMicAnchorPresenter = new LiveLinkMicAnchorPresenter(mContext, mLivePlayViewHolder, false, mLiveSDK, null);
mLiveRyLinkMicPkPresenter = new LiveRyLinkMicPkPresenter(mContext, mLivePlayViewHolder, false, null);
//直播间背景
ImgLoader.displayBlurLive(mContext, mLiveBean.getAvatar(), liveBack);
mask.setVisibility(View.VISIBLE);
mLivePlayViewHolder.setCover(data.getThumb());
mLivePlayViewHolder.play(data.getPull());
mLiveRoomViewHolder.setAvatar(data.getAvatar());
mLiveRoomViewHolder.setAnchorLevel(data.getLevelAnchor());
mLiveRoomViewHolder.setName(data.getUserNiceName());
mLiveRoomViewHolder.setRoomNum(data.getLiangNameTip());
mLiveRoomViewHolder.setTitle(data.getTitle());
mLiveRyLinkMicPkPresenter.setLiveUid(data.getUid(), "");
mLiveRoomViewHolder.setLiveUid(data.getUid());
mSocketRyClient = new SocketRyClient(mLiveBean.getUid(), PortraitLiveManager.this);
if (mLiveLinkMicPresenter != null) {
mLiveLinkMicPresenter.setSocketClient(mSocketClient);
} }
} //心愿单
LiveHttpUtil.getWishList(mLiveBean.getUid(), new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
if (info.length > 0) {
String json = info[0];
WishlistModel model = GsonUtils.fromJson(json, WishlistModel.class);
if (mLiveRoomViewHolder != null && model != null) {
mLiveRoomViewHolder.initWishList(model.getWishlist());
@Override }
public void onFinish() {
}
}
@Override
public void onFinish() {
}
});
enterRoom(); enterRoom();
mLiveRoomViewHolder.initHourRankList();
} }
}); });
mLiveRoomViewHolder.initHourRankList();
} }
@Override @Override
public void onRemove() { public void onRemove() {
//子线程执行退出操作
liveHandler.post(() -> exitLiveRoom());
IMLoginManager.get(mContext).setisNewUserOne(false);
//子线程执行退出操作
endPlay();
exitLiveRoom();
if (mLiveAudienceViewHolder != null) { if (mLiveAudienceViewHolder != null) {
mLiveAudienceViewHolder.removeFromParent(); mLiveAudienceViewHolder.removeFromParent();
mLiveAudienceViewHolder.countDownTimerTrickery = null; mLiveAudienceViewHolder.countDownTimerTrickery = null;
mLiveAudienceViewHolder.removeCallbacks(); mLiveAudienceViewHolder.removeCallbacks();
mLiveAudienceViewHolder.release();
} }
mLiveAudienceViewHolder = null; mLiveAudienceViewHolder = null;
//断开socket //断开socket
@ -293,6 +305,7 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
mSocketRyClient = null; mSocketRyClient = null;
//结束播放 //结束播放
if (mLivePlayViewHolder != null) { if (mLivePlayViewHolder != null) {
mLivePlayViewHolder.removeFromParent();
mLivePlayViewHolder.stopPlay(); mLivePlayViewHolder.stopPlay();
mLivePlayViewHolder.release(); mLivePlayViewHolder.release();
} }
@ -317,16 +330,20 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
if (mLiveEndViewHolder != null) { if (mLiveEndViewHolder != null) {
mLiveEndViewHolder.removeFromParent(); mLiveEndViewHolder.removeFromParent();
mLiveEndViewHolder.release();
mLiveEndViewHolder = null; mLiveEndViewHolder = null;
} }
if (mLiveLinkMicPresenter != null) { if (mLiveLinkMicPresenter != null) {
mLiveLinkMicPresenter.clearData(); mLiveLinkMicPresenter.clearData();
mLiveLinkMicPresenter.release();
} }
if (mLiveLinkMicAnchorPresenter != null) { if (mLiveLinkMicAnchorPresenter != null) {
mLiveLinkMicAnchorPresenter.clearData(); mLiveLinkMicAnchorPresenter.clearData();
mLiveLinkMicAnchorPresenter.release();
} }
if (mLiveRyLinkMicPkPresenter != null) { if (mLiveRyLinkMicPkPresenter != null) {
mLiveRyLinkMicPkPresenter.clearData(); mLiveRyLinkMicPkPresenter.clearData();
mLiveRyLinkMicPkPresenter.release();
} }
} }
@ -660,6 +677,7 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
@Override @Override
public void onLiveEnd() { public void onLiveEnd() {
endPlay();
if (!CommonAppConfig.LIVE_ROOM_SCROLL) { if (!CommonAppConfig.LIVE_ROOM_SCROLL) {
if (mViewPager != null) { if (mViewPager != null) {
if (mViewPager.getCurrentItem() != 1) { if (mViewPager.getCurrentItem() != 1) {
@ -667,7 +685,7 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
} }
mViewPager.setCanScroll(false); mViewPager.setCanScroll(false);
} }
endPlay();
} else { } else {
if (mLivePlayViewHolder != null) { if (mLivePlayViewHolder != null) {
mLivePlayViewHolder.stopPlay2(); mLivePlayViewHolder.stopPlay2();
@ -964,10 +982,6 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
private void enterRoom() { private void enterRoom() {
//进入直播间IM //进入直播间IM
mSocketRyClient = new SocketRyClient(mLiveBean.getUid(), this);
if (mLiveLinkMicPresenter != null) {
mLiveLinkMicPresenter.setSocketClient(mSocketClient);
}
timeIndex = 0; timeIndex = 0;
LiveHttpUtil.enterRoom(mLiveBean.getUid(), mLiveBean.getStream(), new HttpCallback() { LiveHttpUtil.enterRoom(mLiveBean.getUid(), mLiveBean.getStream(), new HttpCallback() {
@ -993,7 +1007,6 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
mask.setVisibility(View.GONE); mask.setVisibility(View.GONE);
} }
} }
//回传参数 //回传参数
Bus.get().post(new LiveAudienceEvent() Bus.get().post(new LiveAudienceEvent()
.setType(LiveAudienceEvent.LiveAudienceType.OPEN_PARAMETERS) .setType(LiveAudienceEvent.LiveAudienceType.OPEN_PARAMETERS)
@ -1300,7 +1313,6 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe
if (mLiveRoomViewHolder != null) if (mLiveRoomViewHolder != null)
mLiveRoomViewHolder.clearList(); mLiveRoomViewHolder.clearList();
IMLoginManager.get(mContext).setisNewUserOne(false);
if (countDownTimer != null) { if (countDownTimer != null) {
countDownTimer.cancel(); countDownTimer.cancel();

View File

@ -63,6 +63,7 @@
android:text="@string/buy_guard_info" android:text="@string/buy_guard_info"
android:textColor="#020202" android:textColor="#020202"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -73,6 +74,7 @@
android:layout_height="110dp" android:layout_height="110dp"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:gravity="center"
android:layout_marginEnd="6dp" android:layout_marginEnd="6dp"
android:orientation="vertical" android:orientation="vertical"
android:overScrollMode="never" android:overScrollMode="never"
@ -104,8 +106,8 @@
android:id="@+id/guard_rights" android:id="@+id/guard_rights"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="5dp"
android:layout_marginEnd="16dp" android:layout_marginBottom="10dp"
android:overScrollMode="never" android:overScrollMode="never"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -132,7 +134,7 @@
android:layout_marginTop="25dp" android:layout_marginTop="25dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible"> tools:visibility="gone">
<TextView <TextView
@ -179,11 +181,11 @@
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:visibility="gone"> tools:visibility="visible">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="25dp"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
@ -215,7 +217,7 @@
<Button <Button
android:id="@+id/guard_submit" android:id="@+id/guard_submit"
android:layout_width="267dp" android:layout_width="267dp"
android:layout_height="42dp" android:layout_height="35dp"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:background="@drawable/bg_new_guard_but" android:background="@drawable/bg_new_guard_but"
android:text="繼續守護" android:text="繼續守護"
@ -227,7 +229,7 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout <RelativeLayout
android:layout_width="243dp" android:layout_width="268dp"
android:layout_height="117dp" android:layout_height="117dp"
android:layout_above="@id/guard_rootView" android:layout_above="@id/guard_rootView"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
@ -245,7 +247,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="58dp" android:layout_height="58dp"
android:layout_marginTop="30dp" android:layout_marginTop="30dp"
android:layout_marginStart="125dp" android:layout_marginStart="136dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/guardian_img_wings" android:src="@drawable/guardian_img_wings"
android:visibility="invisible" android:visibility="invisible"

View File

@ -3,8 +3,6 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="44dp" android:layout_height="44dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
> >
<ImageView <ImageView

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/live_user_root_layout" android:id="@+id/live_user_root_layout"
android:layout_width="38dp" android:layout_width="38dp"
android:layout_marginEnd="5dp" android:layout_marginEnd="3dp"
android:layout_height="38dp"> android:layout_height="38dp">
<!-- <ImageView--> <!-- <ImageView-->

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View File

@ -88,7 +88,7 @@
<LinearLayout <LinearLayout
android:id="@+id/group_1" android:id="@+id/group_1"
android:layout_width="142dp" android:layout_width="138dp"
android:layout_height="34dp" android:layout_height="34dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"