안 드 로 이 드 버들붕어 생방송 탄막 효과
분석 하 다.
우선 버들붕어 의 탄막 효 과 를 살 펴 보 자.아래 그림 과 같다.
이것 은 Dota 2 게임 생방송 의 인터페이스 입 니 다.우 리 는 게임 인터페이스 위 에 많은 탄막 이 있 고 생방송 을 보 는 관중 들 이 바로 이곳 에서 토론 을 하 는 것 을 볼 수 있 습 니 다.
그렇다면 이런 인 터 페 이 스 는 어떻게 이 루어 져 야 할 까?사실은 복잡 하지 않 습 니 다.우 리 는 먼저 레이아웃 에 게임 화면 을 표시 하 는 View 를 설치 한 다음 에 게임 화면 위 에 탄막 을 표시 하 는 View 를 덮어 쓰 면 됩 니 다.탄막 의 View 는 완전히 투명 하 게 만들어 야 한다.그러면 게임 인터페이스의 위 에 덮어 도 게임 의 정상 적 인 관람 에 영향 을 주지 않 고 누군가가 탄막 메 시 지 를 보 낼 때 만 탄막 의 View 위 에 메 시 지 를 그리 면 된다.원리 설명도 아래 와 같다.
그러나 우 리 는 탄막 을 볼 수 있 는 것 외 에 도 탄막 을 보 낼 수 있어 야 하기 때문에 탄막 의 View 위 에 조작 인터페이스의 View 를 다시 덮어 야 한다.그리고 우 리 는 조작 인터페이스 에서 탄막 을 보 내 고 선물 을 줄 수 있다.원리 설명도 아래 와 같다.
이렇게 해서 우 리 는 기본 적 인 실현 원 리 를 분석 하고 다음 에 한 걸음 한 걸음 실현 합 시다.
비디오 재생 실현
이 글 의 주 제 는 탄막 효 과 를 실현 하 는 것 이기 때문에 생방송 의 다른 기능 과 관련 되 지 않 기 때문에 우 리 는 VideoView 를 이용 하여 로 컬 영상 을 재생 하여 최 하층 의 게임 인터페이스 를 모 의 한다.
먼저 Android Studio 를 사용 하여 DanmuTest 프로젝트 를 새로 만 든 다음 activity 를 수정 합 니 다.main.xml 의 코드 는 다음 과 같 습 니 다.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
레이아웃 파일 의 코드 는 매우 간단 합 니 다.하나의 VideoView 만 있 습 니 다.중간 표시 로 설정 합 니 다.그리고 MainActivity 의 코드 를 수정 합 니 다.다음 과 같 습 니 다.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoView videoView = (VideoView) findViewById(R.id.video_view);
videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/Pixels.mp4");
videoView.start();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
}
위의 코드 에는 VideoView 의 가장 기본 적 인 용법 이 사용 되 었 다.onCreate()방법 에서 VideoView 의 인 스 턴 스 를 가 져 와 비디오 파일 의 주 소 를 설정 한 다음 start()방법 으로 재생 을 시작 합 니 다.물론,나 는 사전에 SD 의 루트 디 렉 터 리 에 Pixels.mp4 라 는 비디오 파일 을 준비 했다.SD 카드 기능 을 사 용 했 지만 코드 를 간단하게 보기 위해 서 는 실행 권한 처리 에 가입 하지 않 았 습 니 다.따라서 프로젝트 의 targetSdkVersion 을 23 이하 로 지정 하 는 것 을 기억 하 세 요.
또 영상 재생 이 최고의 체험 효 과 를 낼 수 있 도록 몰입 식 패턴 의 표기 법 을 사용 했다.몰입 식 모델 에 대해 아직 이해 하지 못 하 는 친 구 는 나의 지난 글 안 드 로 이 드 상태 표시 줄 마이크로 기 교 를 참고 하여 몰입 식 모델 을 진정 으로 이해 할 수 있 습 니 다.
마지막 으로 저 희 는 AndroidManifest.xml 에서 Activity 를 가로 화면 으로 설정 하고 권한 성명 을 추가 합 니 다.다음 과 같 습 니 다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.guolin.danmutest">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity" android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
OK,이제 프로젝트 를 실행 할 수 있 습 니 다.프로그램 이 시작 되면 자동 으로 동 영상 을 재생 합 니 다.효 과 는 다음 그림 과 같 습 니 다.이렇게 해서 우 리 는 첫 번 째 기능 을 실현 했다.
탄막 효 과 를 실현 하 다.
이어서 우 리 는 탄막 효 과 를 실현 하기 시작 했다.탄막 은 사용자 정의 View 로 그 위 에 주마등 과 유사 한 문자 효 과 를 나 타 낼 수 있다.시청자 들 이 발표 하 는 댓 글 은 모두 탄막 에 표시 되 지만 화면 을 빠르게 옮 겨 상호작용 을 할 수 있 을 뿐만 아니 라 영상의 정상 적 인 시청 에 도 영향 을 주지 않 는 다.
Google 은 이러한 사용자 정의 View 를 직접 작성 할 수 있 습 니 다.물론 인터넷 에서 만들어 진 오픈 소스 프로젝트 를 직접 사용 할 수도 있 습 니 다.그러면 간단하게 탄막 효 과 를 실현 하기 위해 서 저 는 삐 리 삐 리 에서 시 작 된 탄막 효과 라 이브 러 리 DanmakuFlameMaster 를 직접 사용 하려 고 합 니 다.
DanmakuFlameMaster 라 이브 러 리 의 프로젝트 홈 페이지 주 소 는:https://github.com/Bilibili/DanmakuFlameMaster
현재 Android Studio 를 사용 하여 오픈 소스 라 이브 러 리 를 도입 하 는 것 은 정말 좋 은 방법 입 니 다.build.gradle 파일 에 오픈 소스 라 이브 러 리 의존 을 추가 하면 됩 니 다.그러면 저 희 는 app/build.gradle 파일 을 수정 하고 dependencies 패키지 에 다음 과 같은 의존 도 를 추가 합 니 다.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
compile 'com.github.ctiao:DanmakuFlameMaster:0.5.3'
}
이렇게 해서 우 리 는 DanmakuFlameMaster 라 이브 러 리 를 현재 프로젝트 에 도입 했다.그리고 activity 수정main.xml 의 코드 는 다음 과 같 습 니 다.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/danmaku_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Relative Layout 에 DanmakuView 컨트롤 을 추가 한 것 을 볼 수 있 습 니 다.이 컨트롤 은 탄막 정 보 를 표시 하 는 데 사 용 됩 니 다.RelativeLayout 에 추 가 된 컨트롤 이 덮어 쓰기 때문에 DanmakuView 를 VideoView 아래 에 꼭 쓰 십시오.다음은 MainActivity 의 코드 를 수정 합 니 다.저 희 는 여기 서 탄막 표시 논 리 를 추가 합 니 다.다음 과 같 습 니 다.
public class MainActivity extends AppCompatActivity {
private boolean showDanmaku;
private DanmakuView danmakuView;
private DanmakuContext danmakuContext;
private BaseDanmakuParser parser = new BaseDanmakuParser() {
@Override
protected IDanmakus parse() {
return new Danmakus();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoView videoView = (VideoView) findViewById(R.id.video_view);
videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/Pixels.mp4");
videoView.start();
danmakuView = (DanmakuView) findViewById(R.id.danmaku_view);
danmakuView.enableDanmakuDrawingCache(true);
danmakuView.setCallback(new DrawHandler.Callback() {
@Override
public void prepared() {
showDanmaku = true;
danmakuView.start();
generateSomeDanmaku();
}
@Override
public void updateTimer(DanmakuTimer timer) {
}
@Override
public void danmakuShown(BaseDanmaku danmaku) {
}
@Override
public void drawingFinished() {
}
});
danmakuContext = DanmakuContext.create();
danmakuView.prepare(parser, danmakuContext);
}
/**
* View
* @param content
*
* @param withBorder
*
*/
private void addDanmaku(String content, boolean withBorder) {
BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
danmaku.text = content;
danmaku.padding = 5;
danmaku.textSize = sp2px(20);
danmaku.textColor = Color.WHITE;
danmaku.setTime(danmakuView.getCurrentTime());
if (withBorder) {
danmaku.borderColor = Color.GREEN;
}
danmakuView.addDanmaku(danmaku);
}
/**
*
*/
private void generateSomeDanmaku() {
new Thread(new Runnable() {
@Override
public void run() {
while(showDanmaku) {
int time = new Random().nextInt(300);
String content = "" + time + time;
addDanmaku(content, false);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
/**
* sp px 。
*/
public int sp2px(float spValue) {
final float fontScale = getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
@Override
protected void onPause() {
super.onPause();
if (danmakuView != null && danmakuView.isPrepared()) {
danmakuView.pause();
}
}
@Override
protected void onResume() {
super.onResume();
if (danmakuView != null && danmakuView.isPrepared() && danmakuView.isPaused()) {
danmakuView.resume();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
showDanmaku = false;
if (danmakuView != null) {
danmakuView.release();
danmakuView = null;
}
}
......
}
이 를 통 해 알 수 있 듯 이 onCreate()방법 에서 우 리 는 먼저 DanmakuView 컨트롤 의 인 스 턴 스 를 얻 은 다음 에 enableDanmakuDrawingCache()방법 으로 그리 기 효율 을 높이 고 setCallback()방법 으로 리 셋 함 수 를 설정 했다.이 어 DanmakuContext.create()방법 을 호출 하여 DanmakuContext 의 인 스 턴 스 를 만 들 었 습 니 다.DanmakuContext 는 글꼴 설정,최대 디 스 플레이 줄 수 설정 등 다양한 전역 설정 을 설정 할 수 있 습 니 다.여기 서 우 리 는 특별한 요구 가 없 기 때문에 모든 것 을 묵인 한다.
또한,전체 BaseDanmakuParser 를 직접 만 드 는 탄막 해석 기 를 만들어 야 합 니 다.
DanmakuContext 와 BaseDanmakuParser 가 있 으 면 DanmakuView 의 prepare()방법 으로 준 비 를 할 수 있 습 니 다.준비 가 완료 되면 방금 설정 한 리 셋 함수 중의 prepared()방법 을 자동 으로 호출 합 니 다.그리고 우 리 는 여기 서 DanmakuView 의 start()방법 을 호출 하면 DanmakuView 가 정상 적 인 작업 을 시작 할 수 있 습 니 다.
DanmakuView 는 이미 정상적으로 작 동 하고 있 지만 화면 에 아무런 탄막 정보 가 없 으 면 효과 가 보이 지 않 기 때문에 탄막 메 시 지 를 추가 하 는 기능 도 추가 해 야 합 니 다.
addDanmaku()방법 을 관찰 합 니 다.이 방법 은 Danmaku View 에 탄막 메 시 지 를 추가 하 는 데 사 용 됩 니 다.그 중에서 먼저 createDanmaku()방법 을 호출 하여 BaseDanmaku 인 스 턴 스 를 만 들 었 습 니 다.TYPESCROLL_RL 은 이것 이 오른쪽 에서 왼쪽으로 구 르 는 탄막 이 라 고 표시 한 다음 에 우 리 는 탄막 의 내용,글꼴 크기,색상,표시 시간 등 각종 세부 사항 을 설정 할 수 있다.addDanmaku()방법 에 with Border 인자 가 있 습 니 다.이 인 자 는 탄막 메시지 에 테두리 가 있 는 지 여 부 를 지정 하 는 데 사 용 됩 니 다.그래 야 자신 이 보 낸 탄막 과 다른 사람 이 보 낸 탄막 을 구분 할 수 있 습 니 다.
이렇게 하면 우 리 는 가장 기본 적 인 탄막 기능 을 완성 할 수 있 습 니 다.이 제 는 다른 사람 이 보 낸 탄막 메 시 지 를 받 을 때 addDanmaku()방법 으로 이 탄막 을 Danmaku View 에 추가 하면 됩 니 다.그러나 다른 사람 이 보 낸 소식 을 받 는 것 은 인 스 턴 트 메 신 저 기술 과 관련 되 었 다.분명히 이 글 에서 복잡 한 인 스 턴 트 메 신 저 기술 도 설명 할 수 없 을 것 이다.그래서 여기 서 나 는 generateSomeDanmaku()방법 을 써 서 랜 덤 으로 탄막 메 시 지 를 만 들 었 다.그러면 물고기 싸움 과 유사 한 탄막 효 과 를 모 의 할 수 있다.
그 밖 에 우 리 는 onPause(),onResume(),onDestroy()방법 에서 DanmakuView 의 자원 이 방출 될 수 있 도록 논리 적 처 리 를 해 야 한다.
다음 그림 과 같이 프로그램 을 다시 실행 합 니 다.
이렇게 해서 우 리 는 두 번 째 단계 의 기능 도 실현 했다.
조작 인터페이스 가입
그러면 세 번 째 기능 을 실현 하고 탄막 메 시 지 를 보 내 는 조작 인터페이스 에 가입 하 겠 습 니 다.
우선 activity 수정main.xml 의 코드 는 다음 과 같 습 니 다.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
......
<LinearLayout
android:id="@+id/operation_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="#fff"
android:visibility="gone">
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Send" />
</LinearLayout>
</RelativeLayout>
여기 서 우 리 는 조작 인터페이스 로 Linear Layout 를 추가 한 것 을 볼 수 있다.LinearLayout 에는 복잡 한 컨트롤 이 없습니다.내용 을 입력 하 는 데 사용 되 는 EditText 만 있 고,단추 하 나 는 탄막 을 보 내 는 데 사 용 됩 니 다.처음에 LinearLayout 를 숨 겼 습 니 다.이 조작 인터페이스 가 VideoView 를 계속 가 릴 수 없 기 때문에 사용자 가 탄막 을 보 내 려 고 할 때 만 표시 해 야 합 니 다.다음은 MainActivity 의 코드 를 수정 하고 이 안에 탄막 을 보 내 는 논 리 를 추가 합 니 다.다음 과 같 습 니 다.
public class MainActivity extends AppCompatActivity {
......
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
final LinearLayout operationLayout = (LinearLayout) findViewById(R.id.operation_layout);
final Button send = (Button) findViewById(R.id.send);
final EditText editText = (EditText) findViewById(R.id.edit_text);
danmakuView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (operationLayout.getVisibility() == View.GONE) {
operationLayout.setVisibility(View.VISIBLE);
} else {
operationLayout.setVisibility(View.GONE);
}
}
});
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String content = editText.getText().toString();
if (!TextUtils.isEmpty(content)) {
addDanmaku(content, true);
editText.setText("");
}
}
});
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) {
onWindowFocusChanged(true);
}
}
});
}
......
}
이곳 의 논 리 는 비교적 간단 합 니 다.우 리 는 먼저 DanmakuView 에 클릭 이 벤트 를 설정 하고 화면 을 클릭 하면 이 클릭 이 벤트 를 촉발 합 니 다.그 다음 에 판단 을 한다.만약 에 조작 인터페이스 가 숨겨 져 있 으 면 이 를 나타 내 고 조작 인터페이스 가 표시 되 어 있 으 면 이 를 숨 기 면 화면 을 클릭 하여 조작 인터페이스의 숨 김 과 표 시 를 간단하게 실현 할 수 있다.그 다음 에 우 리 는 보 내기 단 추 를 누 르 면 이 벤트 를 등록 하고 보 낼 때 EditText 의 입력 내용 을 가 져 온 다음 에 addDanmaku()방법 으로 이 메 시 지 를 Danmaku View 에 추가 합 니 다.또한,이 탄막 은 우리 가 직접 보 낸 것 이기 때문에 addDanmaku()방법의 두 번 째 매개 변 수 는 true 에 전달 해 야 합 니 다.
마지막 으로 시스템 입력 법 이 팝 업 될 때 초점 을 잃 어 버 려 몰입 식 모드 를 종료 하기 때문에 시스템 전역 의 UI 변 화 를 감청 하여 프로그램 이 몰입 식 모드 에 있 을 수 있 도록 한다.
이렇게 하면 우 리 는 모든 코드 를 완성 할 수 있 으 니,지금 은 최종 효 과 를 실행 해 볼 수 있다.영화 가 방영 되 는 동시에 GIF 캡 처 를 해서 생 성 된 파일 이 너무 커서 업로드 할 수 없 기 때문에 여 기 는 제 가 영화 가 멈 춘 상태 에서 작 동 했 습 니 다.효 과 는 다음 그림 과 같다.
우리 가 보 낸 탄막 은 녹색 테두리 로 둘러싸 여 있어 다른 탄막 과 쉽게 분리 되 는 것 을 볼 수 있다.
이렇게 해서 우 리 는 세 번 째 단계 의 기능 도 실현 했다.
비록 지금 우 리 는 매우 좋 은 탄막 효 과 를 성공 적 으로 실현 하 였 지만,사실은 이것 은 단지 DanmakuFlameMaster 창고 가 제공 하 는 가장 기본 적 인 기능 일 뿐이다.삐 리 삐 리 가 제공 하 는 이 탄막 오픈 소스 라 이브 러 리 는 매우 풍부 한 기능 을 가지 고 있 으 며,각종 탄막 스타일,특수 효과 등 을 포함한다.그러나 이 글 의 주요 목 표 는 탄막 효과 가 실현 되 는 방향 을 알 리 는 것 이지 DanmakuFlameMaster 라 이브 러 리 에 대해 전면적 인 분석 을 하 는 것 이 아니다.이 라 이브 러 리 에 관심 이 많다 면 github 홈 페이지 에서 더 많은 용법 을 배 울 수 있 습 니 다.
위 에서 말 한 것 은 편집장 님 께 서 소개 해 주신 안 드 로 이 드 버들붕어 생방송 의 탄막 효과 입 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.