├── .gitattributes ├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── BarrageView.iml ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── anler │ │ └── barrage │ │ └── barrageview │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── anler │ │ │ └── barrage │ │ │ └── barrageview │ │ │ ├── BarrageView.java │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── anler │ └── barrage │ └── barrageview │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── output ├── BarrageView-1.4.jar └── show2.gif └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | BarrageView -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BarrageView.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BarrageView 2 | a custom view 3 | 4 | something like this:![](https://github.com/Anler2015/BarrageView/blob/master/output/show2.gif) 5 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.anler.barrage.barrageview" 9 | minSdkVersion 15 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | 23 | 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | compile 'com.android.support:appcompat-v7:22.1.1' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\AndroidSDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/anler/barrage/barrageview/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.anler.barrage.barrageview; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/anler/barrage/barrageview/BarrageView.java: -------------------------------------------------------------------------------- 1 | package com.anler.barrage.barrageview; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.Point; 7 | import android.graphics.Rect; 8 | import android.text.TextPaint; 9 | import android.util.AttributeSet; 10 | import android.util.Log; 11 | import android.view.MotionEvent; 12 | import android.view.View; 13 | 14 | 15 | import java.util.LinkedList; 16 | import java.util.Random; 17 | 18 | /** 19 | * Created by Anler on 2015/10/26. 20 | */ 21 | public class BarrageView extends View { 22 | 23 | enum showMode{ 24 | allScreen, 25 | topOfScreen, 26 | bottomOfScreen 27 | } 28 | 29 | private TextPaint txtPaint; 30 | private int screenHeight; 31 | private int screenWidth; 32 | private int x,y = 0; 33 | private LinkedList pos = new LinkedList(); 34 | private LinkedList txts = new LinkedList(); 35 | private LinkedList txtPaints = new LinkedList(); 36 | 37 | private LinkedList centerPos = new LinkedList(); 38 | private LinkedList centetTxtPaints = new LinkedList(); 39 | private LinkedList centerTxts = new LinkedList(); 40 | 41 | private int speed = 4; 42 | private int txtSize = 30; 43 | private showMode mShowMode = showMode.topOfScreen; 44 | private Random random = new Random(); 45 | private int showSeconds = 3; 46 | 47 | public BarrageView(Context context) { 48 | this(context, null); 49 | } 50 | 51 | public BarrageView(Context context, AttributeSet attrs) { 52 | super(context, attrs); 53 | init(); 54 | } 55 | 56 | private void init() 57 | { 58 | txtPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 59 | txtPaint.setTextSize(txtSize); 60 | Rect rect = new Rect(); 61 | getWindowVisibleDisplayFrame(rect); 62 | screenWidth = rect.width(); 63 | screenHeight = rect.height(); 64 | } 65 | 66 | @Override 67 | protected void onDraw(Canvas canvas) { 68 | super.onDraw(canvas); 69 | for(int i =0;i= 1000 * showSeconds) 99 | { 100 | centerPos.remove(i); 101 | centerTxts.remove(i); 102 | centetTxtPaints.remove(i); 103 | } 104 | } 105 | 106 | } 107 | 108 | 109 | public void setTextSize(int txtSize) 110 | { 111 | this.txtSize = txtSize; 112 | txtPaint.setTextSize(txtSize); 113 | } 114 | 115 | public void setTextColor(int color) 116 | { 117 | txtPaint.setColor(color); 118 | } 119 | 120 | public void setSpeed(int speed) 121 | { 122 | this.speed = speed; 123 | } 124 | 125 | public void setY(int y) 126 | { 127 | this.y = y; 128 | } 129 | 130 | public void setShowSceonds(int i) 131 | { 132 | this.showSeconds = i; 133 | } 134 | 135 | public int setYShowMode(showMode mode) 136 | { 137 | switch (mode) 138 | { 139 | case allScreen: 140 | y = random.nextInt(screenHeight-txtSize)+txtSize; 141 | break; 142 | case topOfScreen: 143 | y = random.nextInt(screenHeight / 2 - txtSize) + txtSize; 144 | break; 145 | case bottomOfScreen: 146 | y = random.nextInt(screenHeight / 2 - txtSize) + screenHeight/2-txtSize; 147 | break; 148 | } 149 | return y; 150 | } 151 | 152 | 153 | @Override 154 | public boolean onTouchEvent(MotionEvent event) { 155 | switch(event.getAction()) 156 | { 157 | case MotionEvent.ACTION_DOWN: 158 | speed = 0; 159 | break; 160 | case MotionEvent.ACTION_UP: 161 | speed = 4; 162 | break; 163 | } 164 | return true; 165 | } 166 | 167 | public void sendBarrage(String txt) 168 | { 169 | pos.add(new Point(screenWidth, setYShowMode(mShowMode))); 170 | TextPaint newPanit = new TextPaint(txtPaint); 171 | txtPaints.add(newPanit); 172 | txts.add(txt); 173 | } 174 | 175 | public void sendBarrageOnCenter(String txt) 176 | { 177 | centerTxts.add(txt); 178 | x = (int)(screenWidth - txtPaint.measureText(centerTxts.getLast()))/2; 179 | centerPos.add(new centerPoint(x, setYShowMode(showMode.bottomOfScreen))); 180 | centerPos.getLast().startTime = System.currentTimeMillis(); 181 | TextPaint newPanit = new TextPaint(txtPaint); 182 | centetTxtPaints.add(newPanit); 183 | } 184 | 185 | public void clearScreen() 186 | { 187 | pos.clear(); 188 | txts.clear(); 189 | txtPaints.clear(); 190 | centerTxts.clear(); 191 | centetTxtPaints.clear(); 192 | centerPos.clear(); 193 | } 194 | 195 | class centerPoint{ 196 | int x,y; 197 | long startTime,endTime; 198 | 199 | public centerPoint(int x, int y) { 200 | this.x = x; 201 | this.y = y; 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /app/src/main/java/com/anler/barrage/barrageview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.anler.barrage.barrageview; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import java.util.Random; 11 | 12 | public class MainActivity extends Activity { 13 | public static final int DELAY_TIME = 800; 14 | Random random = new Random(); 15 | BarrageView barrageView; 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | barrageView = (BarrageView)findViewById(R.id.barrage); 21 | Button btn = (Button) findViewById(R.id.btn); 22 | Button btn1 = (Button) findViewById(R.id.btn1); 23 | 24 | btn.setOnClickListener(new View.OnClickListener() { 25 | @Override 26 | public void onClick(View v) { 27 | barrageView.sendBarrageOnCenter("今天很开心"); 28 | } 29 | }); 30 | btn1.setOnClickListener(new View.OnClickListener() { 31 | @Override 32 | public void onClick(View v) { 33 | barrageView.clearScreen(); 34 | } 35 | }); 36 | final Handler handler = new Handler(); 37 | Runnable createBarrageView = new Runnable() { 38 | @Override 39 | public void run() { 40 | int color = Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256)); 41 | barrageView.setTextColor(color); 42 | barrageView.sendBarrage("你好"); 43 | barrageView.setTextSize(random.nextInt(100)); 44 | handler.postDelayed(this, DELAY_TIME); 45 | } 46 | }; 47 | handler.post(createBarrageView); 48 | 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 |