主题:直播和作品按钮页面
This commit is contained in:
parent
669e2457a9
commit
d19d0cc631
|
|
@ -197,6 +197,11 @@
|
||||||
android:name="com.example.livestreaming.UserProfileActivity"
|
android:name="com.example.livestreaming.UserProfileActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.PublishCenterActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:screenOrientation="portrait" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.example.livestreaming.WishTreeActivity"
|
android:name="com.example.livestreaming.WishTreeActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,8 @@ public class MainActivity extends AppCompatActivity {
|
||||||
binding.fabAddLive.setOnClickListener(new DebounceClickListener() {
|
binding.fabAddLive.setOnClickListener(new DebounceClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDebouncedClick(View v) {
|
public void onDebouncedClick(View v) {
|
||||||
showCreateRoomDialog();
|
// 跳转到发布中心页面
|
||||||
|
PublishCenterActivity.start(MainActivity.this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -539,7 +539,7 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
|
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PublishWorkActivity.start(this);
|
PublishCenterActivity.start(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 悬浮按钮(固定显示)
|
// 悬浮按钮(固定显示)
|
||||||
|
|
@ -548,7 +548,7 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
|
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PublishWorkActivity.start(this);
|
PublishCenterActivity.start(this);
|
||||||
});
|
});
|
||||||
binding.likedGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
binding.likedGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
||||||
binding.favGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
binding.favGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
||||||
|
|
@ -578,7 +578,7 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
|
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PublishWorkActivity.start(this);
|
PublishCenterActivity.start(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
loadMyWorks();
|
loadMyWorks();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,373 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.example.livestreaming.databinding.ActivityPublishCenterBinding;
|
||||||
|
import com.example.livestreaming.net.ApiClient;
|
||||||
|
import com.example.livestreaming.net.ApiResponse;
|
||||||
|
import com.example.livestreaming.net.CategoryResponse;
|
||||||
|
import com.example.livestreaming.net.CreateRoomRequest;
|
||||||
|
import com.example.livestreaming.net.FileUploadResponse;
|
||||||
|
import com.example.livestreaming.net.Room;
|
||||||
|
import com.example.livestreaming.net.StreamUrls;
|
||||||
|
import com.example.livestreaming.net.WorksRequest;
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
public class PublishCenterActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityPublishCenterBinding binding;
|
||||||
|
private int currentTab = 0;
|
||||||
|
private List<CategoryResponse> categoryList = new ArrayList<>();
|
||||||
|
private int selectedCategoryId = -1;
|
||||||
|
private Uri dynamicCoverUri = null;
|
||||||
|
private ActivityResultLauncher<Intent> imagePickerLauncher;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
context.startActivity(new Intent(context, PublishCenterActivity.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (!AuthHelper.requireLogin(this, "发布内容需要登录")) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
binding = ActivityPublishCenterBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
setupImagePicker();
|
||||||
|
setupToolbar();
|
||||||
|
setupTabs();
|
||||||
|
setupClickListeners();
|
||||||
|
loadCategories();
|
||||||
|
showTab(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupImagePicker() {
|
||||||
|
imagePickerLauncher = registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
result -> {
|
||||||
|
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
|
||||||
|
Uri uri = result.getData().getData();
|
||||||
|
if (uri != null) {
|
||||||
|
dynamicCoverUri = uri;
|
||||||
|
showDynamicCover(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupToolbar() {
|
||||||
|
binding.btnBack.setOnClickListener(v -> finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupTabs() {
|
||||||
|
binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onTabSelected(TabLayout.Tab tab) { showTab(tab.getPosition()); }
|
||||||
|
@Override
|
||||||
|
public void onTabUnselected(TabLayout.Tab tab) {}
|
||||||
|
@Override
|
||||||
|
public void onTabReselected(TabLayout.Tab tab) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupClickListeners() {
|
||||||
|
binding.btnStartLive.setOnClickListener(v -> startMobileLive());
|
||||||
|
binding.btnPublishDynamic.setOnClickListener(v -> publishDynamic());
|
||||||
|
binding.dynamicCoverContainer.setOnClickListener(v -> pickDynamicCover());
|
||||||
|
binding.btnRemoveDynamicCover.setOnClickListener(v -> removeDynamicCover());
|
||||||
|
binding.btnPublishWork.setOnClickListener(v -> PublishWorkActivity.start(this));
|
||||||
|
binding.btnCopyStreamUrl.setOnClickListener(v -> copyToClipboard("推流地址", binding.tvStreamUrl.getText().toString()));
|
||||||
|
binding.btnCopyStreamKey.setOnClickListener(v -> copyToClipboard("推流码", binding.tvStreamKey.getText().toString()));
|
||||||
|
binding.btnGetStreamInfo.setOnClickListener(v -> createPcLiveRoom());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showTab(int position) {
|
||||||
|
currentTab = position;
|
||||||
|
binding.contentMobileLive.setVisibility(View.GONE);
|
||||||
|
binding.contentDynamic.setVisibility(View.GONE);
|
||||||
|
binding.contentWork.setVisibility(View.GONE);
|
||||||
|
binding.contentPcLive.setVisibility(View.GONE);
|
||||||
|
switch (position) {
|
||||||
|
case 0: binding.contentMobileLive.setVisibility(View.VISIBLE); break;
|
||||||
|
case 1: binding.contentDynamic.setVisibility(View.VISIBLE); break;
|
||||||
|
case 2: binding.contentWork.setVisibility(View.VISIBLE); break;
|
||||||
|
case 3: binding.contentPcLive.setVisibility(View.VISIBLE); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCategories() {
|
||||||
|
ApiClient.getService(this).getLiveRoomCategories().enqueue(new Callback<ApiResponse<List<CategoryResponse>>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<List<CategoryResponse>>> call, Response<ApiResponse<List<CategoryResponse>>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
|
||||||
|
categoryList = response.body().getData();
|
||||||
|
if (categoryList == null) categoryList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
setupCategorySpinner();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<List<CategoryResponse>>> call, Throwable t) {
|
||||||
|
setupCategorySpinner();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupCategorySpinner() {
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
names.add("请选择分类");
|
||||||
|
for (CategoryResponse cat : categoryList) names.add(cat.getName());
|
||||||
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, names);
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
binding.spinnerPcCategory.setAdapter(adapter);
|
||||||
|
binding.spinnerPcCategory.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(android.widget.AdapterView<?> parent, View view, int pos, long id) {
|
||||||
|
selectedCategoryId = (pos > 0 && pos <= categoryList.size()) ? categoryList.get(pos - 1).getId() : -1;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(android.widget.AdapterView<?> parent) { selectedCategoryId = -1; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startMobileLive() {
|
||||||
|
String title = binding.etLiveTitle.getText().toString().trim();
|
||||||
|
if (TextUtils.isEmpty(title)) title = "我的直播间";
|
||||||
|
Intent intent = new Intent(this, BroadcastActivity.class);
|
||||||
|
intent.putExtra("title", title);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pickDynamicCover() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_PICK);
|
||||||
|
intent.setType("image/*");
|
||||||
|
imagePickerLauncher.launch(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDynamicCover(Uri uri) {
|
||||||
|
binding.ivDynamicCover.setVisibility(View.VISIBLE);
|
||||||
|
binding.dynamicCoverPlaceholder.setVisibility(View.GONE);
|
||||||
|
binding.btnRemoveDynamicCover.setVisibility(View.VISIBLE);
|
||||||
|
Glide.with(this).load(uri).centerCrop().into(binding.ivDynamicCover);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeDynamicCover() {
|
||||||
|
dynamicCoverUri = null;
|
||||||
|
binding.ivDynamicCover.setVisibility(View.GONE);
|
||||||
|
binding.dynamicCoverPlaceholder.setVisibility(View.VISIBLE);
|
||||||
|
binding.btnRemoveDynamicCover.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishDynamic() {
|
||||||
|
String content = binding.etDynamicContent.getText().toString().trim();
|
||||||
|
if (TextUtils.isEmpty(content)) {
|
||||||
|
Toast.makeText(this, "请输入动态内容", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (content.length() > 1000) {
|
||||||
|
Toast.makeText(this, "内容不能超过1000字", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
binding.btnPublishDynamic.setEnabled(false);
|
||||||
|
binding.btnPublishDynamic.setText("发布中...");
|
||||||
|
|
||||||
|
if (dynamicCoverUri != null) {
|
||||||
|
// 用户选择了封面,上传后发布
|
||||||
|
uploadDynamicCoverAndPublish(content);
|
||||||
|
} else {
|
||||||
|
// 用户没选封面,使用特殊标记(纯文字动态)
|
||||||
|
// 使用 "text_only" 作为标记,在展示时识别为纯文字动态
|
||||||
|
doPublishDynamic(content, "text_only");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadDynamicCoverAndPublish(String content) {
|
||||||
|
try {
|
||||||
|
File file = uriToFile(dynamicCoverUri);
|
||||||
|
if (file == null) {
|
||||||
|
Toast.makeText(this, "无法读取图片", Toast.LENGTH_SHORT).show();
|
||||||
|
resetDynamicButton();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
|
||||||
|
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
|
||||||
|
RequestBody model = RequestBody.create(MediaType.parse("text/plain"), "work");
|
||||||
|
RequestBody pid = RequestBody.create(MediaType.parse("text/plain"), "0");
|
||||||
|
ApiClient.getService(this).uploadImage(body, model, pid).enqueue(new Callback<ApiResponse<FileUploadResponse>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<FileUploadResponse>> call, Response<ApiResponse<FileUploadResponse>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
|
||||||
|
FileUploadResponse data = response.body().getData();
|
||||||
|
doPublishDynamic(content, data != null ? data.getUrl() : null);
|
||||||
|
} else {
|
||||||
|
resetDynamicButton();
|
||||||
|
Toast.makeText(PublishCenterActivity.this, "封面上传失败", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<FileUploadResponse>> call, Throwable t) {
|
||||||
|
resetDynamicButton();
|
||||||
|
Toast.makeText(PublishCenterActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
resetDynamicButton();
|
||||||
|
Toast.makeText(this, "图片处理失败", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPublishDynamic(String content, String coverUrl) {
|
||||||
|
WorksRequest request = new WorksRequest();
|
||||||
|
request.setTitle("");
|
||||||
|
request.setDescription(content);
|
||||||
|
request.setType("IMAGE");
|
||||||
|
request.setImageUrls(new ArrayList<>());
|
||||||
|
request.setCoverUrl(coverUrl != null ? coverUrl : "");
|
||||||
|
ApiClient.getService(this).publishWork(request).enqueue(new Callback<ApiResponse<Long>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<Long>> call, Response<ApiResponse<Long>> response) {
|
||||||
|
resetDynamicButton();
|
||||||
|
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
|
||||||
|
Toast.makeText(PublishCenterActivity.this, "动态发布成功", Toast.LENGTH_SHORT).show();
|
||||||
|
binding.etDynamicContent.setText("");
|
||||||
|
removeDynamicCover();
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
String msg = response.body() != null ? response.body().getMessage() : "发布失败";
|
||||||
|
Toast.makeText(PublishCenterActivity.this, msg, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<Long>> call, Throwable t) {
|
||||||
|
resetDynamicButton();
|
||||||
|
Toast.makeText(PublishCenterActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetDynamicButton() {
|
||||||
|
binding.btnPublishDynamic.setEnabled(true);
|
||||||
|
binding.btnPublishDynamic.setText("发布动态");
|
||||||
|
}
|
||||||
|
|
||||||
|
private File uriToFile(Uri uri) {
|
||||||
|
try {
|
||||||
|
InputStream is = getContentResolver().openInputStream(uri);
|
||||||
|
if (is == null) return null;
|
||||||
|
File file = new File(getCacheDir(), "temp_cover_" + System.currentTimeMillis() + ".jpg");
|
||||||
|
FileOutputStream os = new FileOutputStream(file);
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
int len;
|
||||||
|
while ((len = is.read(buf)) != -1) os.write(buf, 0, len);
|
||||||
|
is.close();
|
||||||
|
os.close();
|
||||||
|
return file;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPcLiveRoom() {
|
||||||
|
String title = binding.etPcLiveTitle.getText().toString().trim();
|
||||||
|
if (TextUtils.isEmpty(title)) {
|
||||||
|
Toast.makeText(this, "请输入直播标题", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (selectedCategoryId <= 0) {
|
||||||
|
Toast.makeText(this, "请选择直播分类", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
binding.btnGetStreamInfo.setEnabled(false);
|
||||||
|
binding.btnGetStreamInfo.setText("创建中...");
|
||||||
|
binding.streamInfoLoading.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
// 获取当前用户昵称作为主播名称
|
||||||
|
String streamerName = com.example.livestreaming.net.AuthStore.getNickname(this);
|
||||||
|
if (TextUtils.isEmpty(streamerName)) {
|
||||||
|
streamerName = title; // 如果没有昵称,使用标题
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateRoomRequest request = new CreateRoomRequest(title, streamerName, "pc");
|
||||||
|
request.setCategoryId(selectedCategoryId);
|
||||||
|
|
||||||
|
ApiClient.getService(this).createRoom(request).enqueue(new Callback<ApiResponse<Room>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<Room>> call, Response<ApiResponse<Room>> response) {
|
||||||
|
binding.btnGetStreamInfo.setEnabled(true);
|
||||||
|
binding.btnGetStreamInfo.setText("创建直播间并获取推流信息");
|
||||||
|
binding.streamInfoLoading.setVisibility(View.GONE);
|
||||||
|
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
|
||||||
|
Room room = response.body().getData();
|
||||||
|
if (room != null) {
|
||||||
|
showStreamInfo(room);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(PublishCenterActivity.this, "创建成功但未获取到推流信息", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = response.body() != null ? response.body().getMessage() : "创建直播间失败";
|
||||||
|
Toast.makeText(PublishCenterActivity.this, msg, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<Room>> call, Throwable t) {
|
||||||
|
binding.btnGetStreamInfo.setEnabled(true);
|
||||||
|
binding.btnGetStreamInfo.setText("创建直播间并获取推流信息");
|
||||||
|
binding.streamInfoLoading.setVisibility(View.GONE);
|
||||||
|
Toast.makeText(PublishCenterActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showStreamInfo(Room room) {
|
||||||
|
binding.streamInfoContent.setVisibility(View.VISIBLE);
|
||||||
|
String streamKey = room.getStreamKey();
|
||||||
|
StreamUrls streamUrls = room.getStreamUrls();
|
||||||
|
String pushUrl = (streamUrls != null && streamUrls.getRtmp() != null) ? streamUrls.getRtmp() : "";
|
||||||
|
binding.tvStreamUrl.setText(!TextUtils.isEmpty(pushUrl) ? pushUrl : "未获取到推流地址");
|
||||||
|
binding.tvStreamKey.setText(!TextUtils.isEmpty(streamKey) ? streamKey : "未获取到推流码");
|
||||||
|
Toast.makeText(this, "直播间创建成功!", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyToClipboard(String label, String text) {
|
||||||
|
if (TextUtils.isEmpty(text) || text.startsWith("未获取")) {
|
||||||
|
Toast.makeText(this, "内容为空", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||||
|
if (clipboard != null) {
|
||||||
|
clipboard.setPrimaryClip(ClipData.newPlainText(label, text));
|
||||||
|
Toast.makeText(this, label + "已复制", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,7 +59,10 @@ public class WorksAdapter extends RecyclerView.Adapter<WorksAdapter.WorksViewHol
|
||||||
}
|
}
|
||||||
|
|
||||||
static class WorksViewHolder extends RecyclerView.ViewHolder {
|
static class WorksViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final View coverContainer;
|
||||||
|
private final View textContentContainer;
|
||||||
private final ImageView coverImage;
|
private final ImageView coverImage;
|
||||||
|
private final TextView contentText;
|
||||||
private final TextView titleText;
|
private final TextView titleText;
|
||||||
private final TextView authorText;
|
private final TextView authorText;
|
||||||
private final TextView likeCountText;
|
private final TextView likeCountText;
|
||||||
|
|
@ -67,7 +70,10 @@ public class WorksAdapter extends RecyclerView.Adapter<WorksAdapter.WorksViewHol
|
||||||
|
|
||||||
public WorksViewHolder(@NonNull View itemView) {
|
public WorksViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
coverContainer = itemView.findViewById(R.id.coverContainer);
|
||||||
|
textContentContainer = itemView.findViewById(R.id.textContentContainer);
|
||||||
coverImage = itemView.findViewById(R.id.worksCoverImage);
|
coverImage = itemView.findViewById(R.id.worksCoverImage);
|
||||||
|
contentText = itemView.findViewById(R.id.worksContentText);
|
||||||
titleText = itemView.findViewById(R.id.worksTitleText);
|
titleText = itemView.findViewById(R.id.worksTitleText);
|
||||||
authorText = itemView.findViewById(R.id.worksAuthorText);
|
authorText = itemView.findViewById(R.id.worksAuthorText);
|
||||||
likeCountText = itemView.findViewById(R.id.worksLikeCountText);
|
likeCountText = itemView.findViewById(R.id.worksLikeCountText);
|
||||||
|
|
@ -82,18 +88,36 @@ public class WorksAdapter extends RecyclerView.Adapter<WorksAdapter.WorksViewHol
|
||||||
"title=" + works.getTitle() +
|
"title=" + works.getTitle() +
|
||||||
", userName=" + works.getUserName() +
|
", userName=" + works.getUserName() +
|
||||||
", authorName=" + works.getAuthorName() +
|
", authorName=" + works.getAuthorName() +
|
||||||
", likeCount=" + works.getLikeCount());
|
", likeCount=" + works.getLikeCount() +
|
||||||
|
", coverUrl=" + works.getCoverUrl());
|
||||||
|
|
||||||
// 设置封面图片
|
// 判断是否有有效封面(排除纯文字动态标记)
|
||||||
if (works.getCoverUrl() != null && !works.getCoverUrl().isEmpty()) {
|
String coverUrl = works.getCoverUrl();
|
||||||
|
boolean hasValidCover = coverUrl != null && !coverUrl.isEmpty()
|
||||||
|
&& !coverUrl.equals("text_only"); // 排除纯文字动态标记
|
||||||
|
|
||||||
|
if (hasValidCover) {
|
||||||
|
// 有封面:显示封面图片
|
||||||
|
coverContainer.setVisibility(View.VISIBLE);
|
||||||
|
textContentContainer.setVisibility(View.GONE);
|
||||||
|
|
||||||
Glide.with(itemView.getContext())
|
Glide.with(itemView.getContext())
|
||||||
.load(works.getCoverUrl())
|
.load(coverUrl)
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
.placeholder(R.drawable.bg_cover_placeholder)
|
.placeholder(R.drawable.bg_cover_placeholder)
|
||||||
.error(R.drawable.bg_cover_placeholder)
|
.error(R.drawable.bg_cover_placeholder)
|
||||||
.into(coverImage);
|
.into(coverImage);
|
||||||
} else {
|
} else {
|
||||||
coverImage.setImageResource(R.drawable.bg_cover_placeholder);
|
// 无封面:显示文字内容
|
||||||
|
coverContainer.setVisibility(View.GONE);
|
||||||
|
textContentContainer.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
String content = works.getDescription();
|
||||||
|
if (content != null && !content.isEmpty()) {
|
||||||
|
contentText.setText(content);
|
||||||
|
} else {
|
||||||
|
contentText.setText("暂无内容");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置标题
|
// 设置标题
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
<corners android:radius="8dp" />
|
|
||||||
<stroke
|
<stroke
|
||||||
android:width="1dp"
|
android:width="1dp"
|
||||||
android:color="#CCCCCC"
|
android:color="#CCCCCC"
|
||||||
android:dashWidth="4dp"
|
android:dashWidth="4dp"
|
||||||
android:dashGap="2dp" />
|
android:dashGap="2dp" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
<solid android:color="#F5F5F5" />
|
<solid android:color="#F5F5F5" />
|
||||||
</shape>
|
</shape>
|
||||||
|
|
|
||||||
9
android-app/app/src/main/res/drawable/bg_spinner.xml
Normal file
9
android-app/app/src/main/res/drawable/bg_spinner.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="#DDDDDD" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
</shape>
|
||||||
10
android-app/app/src/main/res/drawable/ic_close_circle_24.xml
Normal file
10
android-app/app/src/main/res/drawable/ic_close_circle_24.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF4757"
|
||||||
|
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
|
||||||
|
</vector>
|
||||||
494
android-app/app/src/main/res/layout/activity_publish_center.xml
Normal file
494
android-app/app/src/main/res/layout/activity_publish_center.xml
Normal file
|
|
@ -0,0 +1,494 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:background="@color/white">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/topBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:elevation="2dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btnBack"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_close_24"
|
||||||
|
android:contentDescription="关闭"
|
||||||
|
app:tint="#333333" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="发布"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tabLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginTop="56dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
app:tabMode="fixed"
|
||||||
|
app:tabGravity="fill"
|
||||||
|
app:tabIndicatorColor="#FF4757"
|
||||||
|
app:tabIndicatorHeight="3dp"
|
||||||
|
app:tabSelectedTextColor="#FF4757"
|
||||||
|
app:tabTextColor="#666666"
|
||||||
|
app:tabRippleColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabItem
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="手机开播" />
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabItem
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="发布动态" />
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabItem
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="发布作品" />
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabItem
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="电脑开播" />
|
||||||
|
|
||||||
|
</com.google.android.material.tabs.TabLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="104dp">
|
||||||
|
|
||||||
|
<!-- 手机开播 -->
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/contentMobileLive"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="手机开播"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="使用手机摄像头进行直播"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#999999" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:hint="直播标题"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etLiveTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="text"
|
||||||
|
android:maxLength="30" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnStartLive"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="52dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:text="开始直播"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:backgroundTint="#FF4757"
|
||||||
|
app:cornerRadius="26dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<!-- 发布动态 -->
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/contentDynamic"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="发布动态"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="快速发布文字动态,可选择添加封面图片"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#999999" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:hint="说点什么..."
|
||||||
|
app:counterEnabled="true"
|
||||||
|
app:counterMaxLength="1000"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etDynamicContent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:minLines="5"
|
||||||
|
android:gravity="top"
|
||||||
|
android:maxLength="1000" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- 封面图片选择(可选) -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="封面图片(可选)"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#666666" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/dynamicCoverContainer"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/bg_dashed_border"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivDynamicCover"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/dynamicCoverPlaceholder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:src="@drawable/ic_add_photo_24"
|
||||||
|
app:tint="#999999" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="添加封面"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#999999" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btnRemoveDynamicCover"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="top|end"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:src="@drawable/ic_close_circle_24"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:contentDescription="移除封面" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnPublishDynamic"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="52dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:text="发布动态"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:backgroundTint="#FF4757"
|
||||||
|
app:cornerRadius="26dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<!-- 发布作品 -->
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/contentWork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="发布作品"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="发布图片或视频作品,支持添加标题、描述等"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#999999" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnPublishWork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="52dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:text="去发布作品"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:backgroundTint="#FF4757"
|
||||||
|
app:cornerRadius="26dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<!-- 电脑开播 -->
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/contentPcLive"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="电脑开播"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="使用OBS等推流软件进行直播"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#999999" />
|
||||||
|
|
||||||
|
<!-- 直播标题 -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:hint="直播标题"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etPcLiveTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="text"
|
||||||
|
android:maxLength="30" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- 分类选择 -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="选择分类"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#666666" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinnerPcCategory"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/bg_spinner"
|
||||||
|
android:paddingHorizontal="12dp" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/streamInfoLoading"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/streamInfoContent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="推流地址"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#666666" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="@drawable/bg_edit_text"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvStreamUrl"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text=""
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btnCopyStreamUrl"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:src="@drawable/ic_copy_24"
|
||||||
|
android:contentDescription="复制"
|
||||||
|
app:tint="#666666" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="推流码"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#666666" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="@drawable/bg_edit_text"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvStreamKey"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text=""
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btnCopyStreamKey"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:src="@drawable/ic_copy_24"
|
||||||
|
android:contentDescription="复制"
|
||||||
|
app:tint="#666666" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnGetStreamInfo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="创建直播间并获取推流信息"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:backgroundTint="#FF4757"
|
||||||
|
app:cornerRadius="24dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="使用说明"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="1. 填写直播标题并选择分类\n2. 点击按钮创建直播间获取推流信息\n3. 下载并安装OBS Studio\n4. 打开OBS,点击设置 - 推流\n5. 服务选择自定义\n6. 将上方的推流地址和推流码填入\n7. 点击开始推流即可"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:lineSpacingExtra="4dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
@ -12,8 +12,9 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!-- 封面图片 -->
|
<!-- 封面图片区域 -->
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
android:id="@+id/coverContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="240dp">
|
android:layout_height="240dp">
|
||||||
|
|
||||||
|
|
@ -49,6 +50,29 @@
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
<!-- 纯文字动态区域(无封面时显示) -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/textContentContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="120dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:background="#F8F8F8"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/worksContentText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:lineSpacingExtra="4dp"
|
||||||
|
android:maxLines="6"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 作品信息 -->
|
<!-- 作品信息 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user