仿b站demo(功能实现篇)

MineImageButton(历史记录): 这里说下第三方的插件类似这样的(@InjectView(R.id.register_account) EditText mRegister_account; )这个插件叫做butterknife-- 注解
可以省去findviewbyid,感觉好用是好用,但是不是很习惯,hhh,毕竟书上和教程视频上都是老老实实的findviewbyid的。 package com.apk.bilibili.activity ;

import android.app.Activity ;
import android.os.Bundle ;
import android.view.Window ;
import android.widget.ListView ;

import com.apk.bilibili.R ;
import com.apk.bilibili.utils.BaseAdapterHelper ;
import com.apk.bilibili.utils.History ;
import com.apk.bilibili.utils.QuickAdapter ;

import java.util.List ;

import cn.bmob.v3.Bmob ;
import cn.bmob.v3.BmobQuery ;
import cn.bmob.v3.listener.FindListener ;

/**
* Created by Administrator on 2016/8/25.
*/
public class MineImageButton extends Activity {
private ListView mHistory_List ;
protected QuickAdapter MineAdapter ;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
requestWindowFeature(Window. FEATURE_NO_TITLE) ;
setContentView(R.layout. mine_imagebutton) ;
Bmob. initialize( MineImageButton. this, "4abc415ca666a3fa6301ad90a0d2fa8d") ;
mHistory_List=(ListView)findViewById(R.id. history_list) ;
initData() ;
queryContent() ;
}
public void initData() {
// TODO Auto-generated method stub
if ( MineAdapter == null) {
MineAdapter = new QuickAdapter( MineImageButton. this, R.layout. history_item) {
@Override
protected void convert(BaseAdapterHelper helper , History history) {
helper.setText(R.id. history_tv , history.getHistory_record()) ;
}
} ;
mHistory_List.setAdapter( MineAdapter) ;
}
}
private void queryContent() {
BmobQuery bmobQuery = new BmobQuery() ;
bmobQuery.findObjects( this, new FindListener() {
@Override
public void onSuccess(List list) {

if (list == null || list.size() == 0) {
MineAdapter.notifyDataSetChanged() ;
return;
}
MineAdapter.addAll(list) ;
mHistory_List.setAdapter( MineAdapter) ;


}

@Override
public void onError( int i , String s) {

}
}) ;


}
}
MineThridImageButton(系统消息): package com.apk.bilibili.activity ;

import android.app.Activity ;
import android.os.Bundle ;
import android.view.Window ;
import android.widget.ListView ;

import com.apk.bilibili.R ;
import com.apk.bilibili.utils.BaseAdapterHelper ;
import com.apk.bilibili.utils.QuickAdapter ;
import com.apk.bilibili.utils.SystemMessage ;


import java.util.List ;
import cn.bmob.v3.Bmob ;
import cn.bmob.v3.BmobQuery ;
import cn.bmob.v3.listener.FindListener ;

public class MineThridImageButton extends Activity {
private ListView listView ;
protected QuickAdapter MineAdapter ;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
requestWindowFeature(Window. FEATURE_NO_TITLE) ;
setContentView(R.layout. mine_thrid_imagebutton) ;
Bmob. initialize(MineThridImageButton. this, "4abc415ca666a3fa6301ad90a0d2fa8d") ;
listView=(ListView)findViewById(R.id. listview) ;
queryContent() ;
initData() ;
}
public void initData() {
// TODO Auto-generated method stub
if ( MineAdapter == null) {
MineAdapter = new QuickAdapter( this, R.layout. item_list) {
@Override
protected void convert(BaseAdapterHelper helper , SystemMessage systemMessage) {
helper.setText(R.id. tv_title , systemMessage.getSystem_message_title()).setText(R.id. tv_content , systemMessage.getMessage_content()) ;
}
} ;
listView.setAdapter( MineAdapter) ;
}
}



private void queryContent() {
BmobQuery bmobQuery = new BmobQuery() ;
bmobQuery.findObjects( this, new FindListener() {
@Override
public void onSuccess(List list) {

if (list == null || list.size() == 0) {
MineAdapter.notifyDataSetChanged() ;
return;
}
MineAdapter.addAll(list) ;
listView.setAdapter( MineAdapter) ;


}

@Override
public void onError( int i , String s) {

}
}) ;


}
}





这里需要说明一下Bmob的查询成功这个方法是需要异步调用的 但是官方文档刚好给出了我需要实现的这么一个功能,所以就直接拿来用了 这里需要几个工具类 QuickAdapter: package com.apk.bilibili.utils ;

/**
* Copyright 2013 Joan Zapata
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.util.List ;

import android.content.Context ;
import android.view.View ;
import android.view.ViewGroup ;
import static com.apk.bilibili.utils.BaseAdapterHelper.get ;

/**
* Abstraction class of a BaseAdapter in which you only need
* to provide the convert() implementation.

* Using the provided BaseAdapterHelper, your code is minimalist.
* @param < T > The type of the items in the list.
*/
public abstract class QuickAdapter< T> extends BaseQuickAdapter< T , BaseAdapterHelper> {

/**
* Create a QuickAdapter.
* @param context The context.
* @param layoutResId The layout resource id of each item.
*/
public QuickAdapter(Context context , int layoutResId) {
super(context , layoutResId) ;
}

/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
* @param context The context.
* @param layoutResId The layout resource id of each item.
* @param data A new list is created out of this one to avoid mutable list
*/
public QuickAdapter(Context context , int layoutResId , List< T> data) {
super(context ,layoutResId ,data) ;
}

protected BaseAdapterHelper getAdapterHelper( int position , View convertView , ViewGroup parent) {
return get( context , convertView , parent , layoutResId , position) ;
}


}
BaseQuickAdapter: package com.apk.bilibili.utils ;

import android.content.Context ;
import android.view.Gravity ;
import android.view.View ;
import android.view.ViewGroup ;
import android.widget.BaseAdapter ;
import android.widget.FrameLayout ;
import android.widget.ProgressBar ;

import java.util.ArrayList ;
import java.util.List ;

/**
* Abstraction class of a BaseAdapter in which you only need
* to provide the convert() implementation.

* Using the provided BaseAdapterHelper, your code is minimalist.
* @param < T > The type of the items in the list.
*/
public abstract class BaseQuickAdapter< T , H extends BaseAdapterHelper> extends BaseAdapter {

protected static final String TAG = BaseQuickAdapter. class.getSimpleName() ;

protected final Context context ;

protected final int layoutResId ;

protected final List< T> data ;

protected boolean displayIndeterminateProgress = false;

/**
* Create a QuickAdapter.
* @param context The context.
* @param layoutResId The layout resource id of each item.
*/
public BaseQuickAdapter(Context context , int layoutResId) {
this(context , layoutResId , null) ;
}

/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
* @param context The context.
* @param layoutResId The layout resource id of each item.
* @param data A new list is created out of this one to avoid mutable list
*/
public BaseQuickAdapter(Context context , int layoutResId , List< T> data) {
this. data = https://www.it610.com/article/data == null ? new ArrayList< T>() : new ArrayList< T>(data) ;
this. context = context ;
this. layoutResId = layoutResId ;
}

@Override
public int getCount() {
int extra = displayIndeterminateProgress ? 1 : 0 ;
return data.size() + extra ;
}

@Override
public T getItem( int position) {
if (position >= data.size()) return null;
return data.get(position) ;
}

@Override
public long getItemId( int position) {
return position ;
}

@Override
public int getViewTypeCount() {
return 2 ;
}

@Override
public int getItemViewType( int position) {
return position >= data.size() ? 1 : 0 ;
}

@Override
public View getView( int position , View convertView , ViewGroup parent) {
if (getItemViewType(position) == 0) {
final H helper = getAdapterHelper(position , convertView , parent) ;
convert(helper , getItem(position)) ;
return helper.getView() ;
}

return createIndeterminateProgressView(convertView , parent) ;
}

private View createIndeterminateProgressView(View convertView , ViewGroup parent) {
if (convertView == null) {
FrameLayout container = new FrameLayout( context) ;
container.setForegroundGravity(Gravity. CENTER) ;
ProgressBar progress = new ProgressBar( context) ;
container.addView(progress) ;
convertView = container ;
}
return convertView ;
}

@Override
public boolean isEnabled( int position) {
return position < data.size() ;
}

public void add( T elem) {
data.add(elem) ;
notifyDataSetChanged() ;
}

public void addAll(List< T> elem) {
data.addAll(elem) ;
notifyDataSetChanged() ;
}

public void set( T oldElem , T newElem) {
set( data.indexOf(oldElem) , newElem) ;
}

public void set( int index , T elem) {
data.set(index , elem) ;
notifyDataSetChanged() ;
}

public void remove( T elem) {
data.remove(elem) ;
notifyDataSetChanged() ;
}

public void remove( int index) {
data.remove(index) ;
notifyDataSetChanged() ;
}

public boolean contains( T elem) {
return data.contains(elem) ;
}

/** Clear data list */
public void clear() {
data.clear() ;
notifyDataSetChanged() ;
}

public void showIndeterminateProgress( boolean display) {
if (display == displayIndeterminateProgress) return;
displayIndeterminateProgress = display ;
notifyDataSetChanged() ;
}

/**
* Implement this method and use the helper to adapt the view to the given item.
* @param helper A fully initialized helper.
* @param item The item that needs to be displayed.
*/
protected abstract void convert( H helper , T item) ;

/**
* You can override this method to use a custom BaseAdapterHelper in order to fit your needs
*
* @param position The position of the item within the adapter's data set of the item whose view we want.
* @param convertView The old view to reuse, if possible. Note: You should check that this view
*is non-null and of an appropriate type before using. If it is not possible to convert
*this view to display the correct data, this method can create a new view.
*Heterogeneous lists can specify their number of view types, so that this View is
*always of the right type (see { @link #getViewTypeCount()} and
*{ @link #getItemViewType(int)}).
* @param parent The parent that this view will eventually be attached to
* @return An instance of BaseAdapterHelper
*/
protected abstract H getAdapterHelper( int position , View convertView , ViewGroup parent) ;

}
BaseAdapterHelper: package com.apk.bilibili.utils ;

/**
* Copyright 2013 Joan Zapata
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/



import android.annotation.TargetApi ;
import android.content.Context ;
import android.graphics.Bitmap ;
import android.graphics.Typeface ;
import android.graphics.drawable.Drawable ;
import android.os.Build ;
import android.text.util.Linkify ;
import android.util.SparseArray ;
import android.view.LayoutInflater ;
import android.view.View ;
import android.view.ViewGroup ;
import android.view.animation.AlphaAnimation ;
import android.widget.ImageView ;
import android.widget.ProgressBar ;
import android.widget.RatingBar ;
import android.widget.TextView ;


/**
* Allows an abstraction of the ViewHolder pattern.

*

*
* Usage
*
*


* return BaseAdapterHelper.get(context, convertView, parent, R.layout.item)
*.setText(R.id.tvName, contact.getName())
*.setText(R.id.tvEmails, contact.getEmails().toString())
*.setText(R.id.tvNumbers, contact.getNumbers().toString())
*.getView();
*


*/
@TargetApi(Build.VERSION_CODES. HONEYCOMB)
public class BaseAdapterHelper {

/** Views indexed with their IDs */
private final SparseArray views ;

private final Context context ;

private int position ;

private View convertView ;

private BaseAdapterHelper(Context context , ViewGroup parent , int layoutId , int position) {
this. context = context ;
this. position = position ;
this. views = new SparseArray() ;
convertView = LayoutInflater. from(context) //
.inflate(layoutId , parent , false) ;
convertView.setTag( this) ;
}

/**
* This method is the only entry point to get a BaseAdapterHelper.
* @param context The current context.
* @param convertView The convertView arg passed to the getView() method.
* @param parent The parent arg passed to the getView() method.
* @return A BaseAdapterHelper instance.
*/
public static BaseAdapterHelper get(Context context , View convertView , ViewGroup parent , int layoutId) {
return get(context , convertView , parent , layoutId , - 1) ;
}

/** This method is package private and should only be used by QuickAdapter. */
static BaseAdapterHelper get(Context context , View convertView , ViewGroup parent , int layoutId , int position) {
if (convertView == null) {
return new BaseAdapterHelper(context , parent , layoutId , position) ;
}
return ( BaseAdapterHelper) convertView.getTag() ;
}

/**
* This method allows you to retrieve a view and perform custom
* operations on it, not covered by the BaseAdapterHelper.

* If you think it's a common use case, please consider creating
* a new issue at https://github.com/JoanZapata/base-adapter-helper/issues.
* @param viewId The id of the view you want to retrieve.
*/
public < T extends View> T getView( int viewId) {
return retrieveView(viewId) ;
}

/**
* Will set the text of a TextView.
* @param viewId The view id.
* @param value The text to put in the text view.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setText( int viewId , String value) {
TextView view = retrieveView(viewId) ;
view.setText(value) ;
return this;
}

/**
* Will set the image of an ImageView from a resource id.
* @param viewId The view id.
* @param imageResId The image resource id.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setImageResource( int viewId , int imageResId) {
ImageView view = retrieveView(viewId) ;
view.setImageResource(imageResId) ;
return this;
}

/**
* Will set background color of a view.
* @param viewId The view id.
* @param color A color, not a resource id.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setBackgroundColor( int viewId , int color) {
View view = retrieveView(viewId) ;
view.setBackgroundColor(color) ;
return this;
}

/**
* Will set background of a view.
* @param viewId The view id.
* @param backgroundRes A resource to use as a background.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setBackgroundRes( int viewId , int backgroundRes) {
View view = retrieveView(viewId) ;
view.setBackgroundResource(backgroundRes) ;
return this;
}

/**
* Will set text color of a TextView.
* @param viewId The view id.
* @param textColor The text color (not a resource id).
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setTextColor( int viewId , int textColor) {
TextView view = retrieveView(viewId) ;
view.setTextColor(textColor) ;
return this;
}

/**
* Will set the image of an ImageView from a drawable.
* @param viewId The view id.
* @param drawable The image drawable.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setImageDrawable( int viewId , Drawable drawable) {
ImageView view = retrieveView(viewId) ;
view.setImageDrawable(drawable) ;
return this;
}



/** Add an action to set the image of an image view. Can be called multiple times. */
public BaseAdapterHelper setImageBitmap( int viewId , Bitmap bitmap) {
ImageView view = retrieveView(viewId) ;
view.setImageBitmap(bitmap) ;
return this;
}

/**
* Add an action to set the alpha of a view. Can be called multiple times.
* Alpha between 0-1.
*/
public BaseAdapterHelper setAlpha( int viewId , float value) {
if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. HONEYCOMB) {
retrieveView(viewId).setAlpha(value) ;
} else {
// Pre-honeycomb hack to set Alpha value
AlphaAnimation alpha = new AlphaAnimation(value , value) ;
alpha.setDuration( 0) ;
alpha.setFillAfter( true) ;
retrieveView(viewId).startAnimation(alpha) ;
}
return this;
}

/**
* Set a view visibility to VISIBLE (true) or GONE (false).
* @param viewId The view id.
* @param visible True for VISIBLE, false for GONE.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setVisible( int viewId , boolean visible) {
View view = retrieveView(viewId) ;
view.setVisibility(visible ? View. VISIBLE : View. GONE) ;
return this;
}

/**
* Add links into a TextView.
* @param viewId The id of the TextView to linkify.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper linkify( int viewId) {
TextView view = retrieveView(viewId) ;
Linkify. addLinks(view , Linkify. ALL) ;
return this;
}

/** Apply the typeface to the given viewId */
public BaseAdapterHelper setTypeface( int viewId , Typeface typeface) {
TextView view = retrieveView(viewId) ;
view.setTypeface(typeface) ;
return this;
}

/** Apply the typeface to all the given viewIds */
public BaseAdapterHelper setTypeface(Typeface typeface , int... viewIds) {
for ( int viewId : viewIds) {
TextView view = retrieveView(viewId) ;
view.setTypeface(typeface) ;
}
return this;
}

/**
* Sets the progress of a ProgressBar.
* @param viewId The view id.
* @param progress The progress.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setProgress( int viewId , int progress) {
ProgressBar view = retrieveView(viewId) ;
view.setProgress(progress) ;
return this;
}

/**
* Sets the progress and max of a ProgressBar.
* @param viewId The view id.
* @param progress The progress.
* @param max The max value of a ProgressBar.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setProgress( int viewId , int progress , int max) {
ProgressBar view = retrieveView(viewId) ;
view.setProgress(progress) ;
view.setMax(max) ;
return this;
}

/**
* Sets the range of a ProgressBar to 0...max.
* @param viewId The view id.
* @param max The max value of a ProgressBar.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setMax( int viewId , int max) {
ProgressBar view = retrieveView(viewId) ;
view.setMax(max) ;
return this;
}

/**
* Sets the rating (the number of stars filled) of a RatingBar.
* @param viewId The view id.
* @param rating The rating.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setRating( int viewId , float rating) {
RatingBar view = retrieveView(viewId) ;
view.setRating(rating) ;
return this;
}

/**
* Sets the rating (the number of stars filled) and max of a RatingBar.
* @param viewId The view id.
* @param rating The rating.
* @param max The range of the RatingBar to 0...max.
* @return The BaseAdapterHelper for chaining.
*/
public BaseAdapterHelper setRating( int viewId , float rating , int max) {
RatingBar view = retrieveView(viewId) ;
view.setRating(rating) ;
view.setMax(max) ;
return this;
}

/** Retrieve the convertView */
public View getView() {
return convertView ;
}

/**
* Retrieve the overall position of the data in the list.
* @throws IllegalArgumentException If the position hasn't been set at the construction of the this helper.
*/
public int getPosition() {
if ( position == - 1)
throw new IllegalStateException( "Use BaseAdapterHelper constructor " +
"with position if you need to retrieve the position.") ;
return position ;
}

@SuppressWarnings( "unchecked")
private < T extends View> T retrieveView( int viewId) {
View view = views.get(viewId) ;
if (view == null) {
view = convertView.findViewById(viewId) ;
views.put(viewId , view) ;
}
return ( T) view ;
}

}
以及bmob建表用的bean类 SystemMessage: package com.apk.bilibili.utils ;

import cn.bmob.v3.BmobObject ;

public class SystemMessage extends BmobObject{
private String system_message_title ;
private String message_content ;
private int message_number ;

public int getMessage_number() {
return message_number ;
}

public void setMessage_number( int message_number) {
this. message_number = message_number ;
}

public String getMessage_content() {
return message_content ;
}

public void setMessage_content(String message_content) {
this. message_content = message_content ;
}



public String getSystem_message_title() {
return system_message_title ;
}

public void setSystem_message_title(String system_message_title) {
this. system_message_title = system_message_title ;
}




} History: package com.apk.bilibili.utils ;

import cn.bmob.v3.BmobObject ;

/**
* Created by Administrator on 2016/8/25.
*/
public class History extends BmobObject {
public String getHistory_record() {
return history_record ;
}

public void setHistory_record(String history_record) {
this. history_record = history_record ;
}

private String history_record ;
}
帐号登录: package com.apk.bilibili.activity ;

import android.app.Activity ;
import android.content.Intent ;
import android.os.Bundle ;
import android.text.Editable ;
import android.text.InputFilter ;
import android.text.TextWatcher ;
import android.text.method.PasswordTransformationMethod ;
import android.view.View ;
import android.view.Window ;
import android.widget.Button ;
import android.widget.EditText ;
import android.widget.ImageView ;
import android.widget.TextView ;
import android.widget.Toast ;

import com.apk.bilibili.R ;

import butterknife.ButterKnife ;
import butterknife.InjectView ;
import cn.bmob.v3.Bmob ;
import cn.bmob.v3.BmobUser ;
import cn.bmob.v3.listener.SaveListener ;


public class SignIn extends Activity {


@InjectView(R.id. account_editText) EditText mAccount_EditText ;
@InjectView(R.id. password_editText) EditText mPassword_EditText ;
@InjectView(R.id. password_imgView) ImageView mPassword_ImgView ;
@InjectView(R.id. account_imgView) ImageView mAccount_ImgView ;
@InjectView(R.id. register_button) Button mRegister_Button ;
@InjectView(R.id. forget_password) TextView mForget_password ;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
requestWindowFeature(Window. FEATURE_NO_TITLE) ;
setContentView(R.layout. sign_in) ;
Bmob. initialize(SignIn. this, "4abc415ca666a3fa6301ad90a0d2fa8d") ;
ButterKnife. inject( this) ;
mPassword_EditText.setFilters( new InputFilter[]{ new InputFilter.LengthFilter( 16)}) ;
mPassword_EditText.setTransformationMethod(PasswordTransformationMethod. getInstance()) ;
mAccount_EditText.addTextChangedListener( Account_TextWatcher) ;
mPassword_EditText.addTextChangedListener( Password_TextWatcher) ;

mForget_password.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent= new Intent(SignIn. this, Query_Account. class) ;
startActivity(intent) ;
}
}) ;
mRegister_Button.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {

Intent intent= new Intent(SignIn. this, Register. class) ;
startActivity(intent) ;
}
}) ;
}

public void login(View view){

String account= mAccount_EditText.getText().toString() ;
String password= mPassword_EditText.getText().toString() ;
final BmobUser bmobUser = new BmobUser() ;
bmobUser.setUsername(account) ;
bmobUser.setPassword(password) ;
bmobUser.login( this, new SaveListener() {

@Override
public void onSuccess() {
Intent intent= new Intent(SignIn. this, Notice. class) ;
startActivity(intent) ;
Toast. makeText(SignIn. this, "登录成功" ,Toast. LENGTH_LONG).show() ;
}

@Override
public void onFailure( int code , String msg) {
Toast. makeText(SignIn. this, "进不去呢( ‘-ω?? )" ,Toast. LENGTH_LONG).show() ;
}
}) ;
}


private TextWatcher Account_TextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s , int start , int before , int count) {
// TODO Auto-generated method stub
mAccount_ImgView.setVisibility(View. VISIBLE) ;
mPassword_ImgView.setVisibility(View. GONE) ;

}

@Override
public void beforeTextChanged(CharSequence s , int start , int count , int after) {
// TODO Auto-generated method stub

}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub

}
} ;
private TextWatcher Password_TextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s , int start , int before , int count) {
// TODO Auto-generated method stub
mAccount_ImgView.setVisibility(View. GONE) ;
mPassword_ImgView.setVisibility(View. VISIBLE) ;

}

@Override
public void beforeTextChanged(CharSequence s , int start , int count , int after) {
// TODO Auto-generated method stub

}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub

}
} ; }
我在onTextChanged方法这里稍微小小的美化了一下

仿b站demo(功能实现篇)
文章图片


当输入密码的时候:

仿b站demo(功能实现篇)
文章图片



我这里还没有想出下一步该怎么写,思路还没有,所以我就没有登录以后的关注功能 注册: package com.apk.bilibili.activity ;

import android.app.Activity ;
import android.os.Bundle ;
import android.text.InputFilter ;
import android.text.method.PasswordTransformationMethod ;
import android.view.View ;
import android.view.Window ;
import android.widget.EditText ;
import android.widget.Toast ;
import com.apk.bilibili.R ;
import com.apk.bilibili.utils.MyUser ;
import butterknife.ButterKnife ;
import butterknife.InjectView ;
import cn.bmob.v3.Bmob ;
import cn.bmob.v3.listener.SaveListener ;

public class Register extends Activity {
@InjectView(R.id. register_account) EditText mRegister_account ;
@InjectView(R.id. register_password) EditText mRegister_password ;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
requestWindowFeature(Window. FEATURE_NO_TITLE) ;
setContentView(R.layout. register) ;
Bmob. initialize(Register. this, "4abc415ca666a3fa6301ad90a0d2fa8d") ;
ButterKnife. inject( this) ;
mRegister_password.setFilters( new InputFilter[]{ new InputFilter.LengthFilter( 16)}) ;
mRegister_password.setTransformationMethod(PasswordTransformationMethod. getInstance()) ;


}
public void submit(View view){

String account= mRegister_account.getText().toString() ;
String password= mRegister_password.getText().toString() ;
if (account.equals( "")||password.equals( "")){
return;
}
MyUser myUser = new MyUser() ;
myUser.setUsername(account) ;
myUser.setPassword(password) ;
myUser.signUp( this, new SaveListener() {
@Override
public void onSuccess() {
Toast. makeText(Register. this, "注册成功" ,Toast. LENGTH_LONG).show() ;
}

@Override
public void onFailure( int i , String s) {
Toast. makeText(Register. this, "注册失败"+ ""+i+ ""+s ,Toast. LENGTH_LONG).show() ;
}
}) ;
}

}



至于视频的播放,我本来想用Vitamio来实现,后来出现了很多问题,看了不少Vitamio的博客,还是没有实现,比如视频的源地址啊,我去翻b站的网站源代码,去载视频地址获取器类似这样的一个软件,找是找到了,但是无法播放,android自带有个videoview控件,但是支持的格式并不是flv的,无奈之下只好用webview来实现了。以至于在Recommend_Fragment中看到的跳转到show这个activity。 广告轮播: Recommend_Fragment中的布局:
android :layout_width= "match_parent"
android :layout_height= "match_parent" >
android :id= "@+id/slideshowView"
android :layout_width= "match_parent"
android :layout_height= "80dp"
/>
android :scrollbars= "none"
android :cacheColorHint= "#000000"
android :horizontalSpacing= "55dp"
android :verticalSpacing= "20dp"
android :numColumns= "2"
android :id= "@+id/gridView"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :layout_below= "@+id/slideshowView"
android :layout_alignParentLeft= "true"
android :layout_alignParentStart= "true" >








SlideShowView: package com.apk.bilibili.utils ;

import java.util.ArrayList ;
import java.util.List ;
import java.util.concurrent.Executors ;
import java.util.concurrent.ScheduledExecutorService ;
import java.util.concurrent.TimeUnit ;


import android.content.Context ;
import android.graphics.drawable.Drawable ;
import android.os.Handler ;
import android.os.Message ;
import android.os.Parcelable ;
import android.support.v4.view.PagerAdapter ;
import android.support.v4.view.ViewPager ;
import android.support.v4.view.ViewPager.OnPageChangeListener ;
import android.util.AttributeSet ;
import android.view.LayoutInflater ;
import android.view.View ;
import android.widget.FrameLayout ;
import android.widget.ImageView ;
import android.widget.ImageView.ScaleType ;

import com.apk.bilibili.R ;


public class SlideShowView extends FrameLayout {
//轮播图图片数量
private final static int IMAGE_COUNT = 2 ;
//自动轮播的时间间隔
private final static int TIME_INTERVAL = 2 ;
//自动轮播启用开关
private final static boolean isAutoPlay = true;

//自定义轮播图的资源ID
private int [] imagesResIds ;
//放轮播图片的ImageView 的list
private List imageViewsList ;
//放圆点的View的list
private List dotViewsList ;

private ViewPager viewPager ;
//当前轮播页
private int currentItem = 0 ;
//定时任务
private ScheduledExecutorService scheduledExecutorService ;
//Handler
private Handler handler = new Handler(){

@Override
public void handleMessage (Message msg) {
// TODO Auto-generated method stub
super .handleMessage(msg) ;
viewPager .setCurrentItem( currentItem ) ;
}

} ;

public SlideShowView(Context context) {
this (context ,null ) ;
// TODO Auto-generated constructor stub
}
public SlideShowView(Context context , AttributeSet attrs) {
this (context , attrs , 0 ) ;
// TODO Auto-generated constructor stub
}
public SlideShowView(Context context , AttributeSet attrs , int defStyle) {
super (context , attrs , defStyle) ;
// TODO Auto-generated constructor stub
initData() ;
initUI(context) ;
if ( isAutoPlay ){
startPlay() ;
}

}
/**
* 开始轮播图切换
*/
private void startPlay (){
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ;
scheduledExecutorService .scheduleAtFixedRate( new SlideShowTask() , 1 , 4 , TimeUnit. SECONDS ) ;
}
/**
* 停止轮播图切换
*/
private void stopPlay (){
scheduledExecutorService .shutdown() ;
}
/**
* 初始化相关Data
*/
private void initData (){
imagesResIds = new int []{ //图片数据
R.drawable. advertisement ,
R.drawable. advertisement_second ,
} ;
imageViewsList = new ArrayList() ;
dotViewsList = new ArrayList() ;

}
/**
* 初始化Views等UI
*/
private void initUI (Context context){
LayoutInflater.from(context).inflate(R.layout. advertisement , this, true ) ;
for ( int imageID : imagesResIds ){
ImageView view = new ImageView(context) ;
view.setImageResource(imageID) ;
view.setScaleType(ScaleType. FIT_XY ) ;
imageViewsList .add(view) ;
}
dotViewsList .add(findViewById(R.id. v_dot1 )) ;
dotViewsList .add(findViewById(R.id. v_dot2 )) ;

viewPager = (ViewPager) findViewById(R.id. viewPager ) ;
viewPager .setFocusable( true ) ;

viewPager .setAdapter( new MyPagerAdapter()) ;
viewPager .setOnPageChangeListener( new MyPageChangeListener()) ;
}

/**
* 填充ViewPager的页面适配器
* @author caizhiming
*/
private class MyPagerAdapter extends PagerAdapter{

@Override
public void destroyItem (View container , int position , Object object) {
// TODO Auto-generated method stub
//((ViewPag.er)container).removeView((View)object);
((ViewPager)container).removeView( imageViewsList .get(position)) ;
}

@Override
public Object instantiateItem (View container , int position) {
// TODO Auto-generated method stub
((ViewPager)container).addView( imageViewsList .get(position)) ;
return imageViewsList .get(position) ;
}

@Override
public int getCount () {
// TODO Auto-generated method stub
return imageViewsList .size() ;
}

@Override
public boolean isViewFromObject (View arg0 , Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1 ;
}
@Override
public void restoreState (Parcelable arg0 , ClassLoader arg1) {
// TODO Auto-generated method stub

}

@Override
public Parcelable saveState () {
// TODO Auto-generated method stub
return null;
}

@Override
public void startUpdate (View arg0) {
// TODO Auto-generated method stub

}

@Override
public void finishUpdate (View arg0) {
// TODO Auto-generated method stub

}

}
/**
* ViewPager的监听器
* 当ViewPager中页面的状态发生改变时调用
* @author caizhiming
*/
private class MyPageChangeListener implements OnPageChangeListener{

boolean isAutoPlay = false;

@Override
public void onPageScrollStateChanged ( int arg0) {
// TODO Auto-generated method stub
switch (arg0) {
case 1 : // 手势滑动,空闲中
isAutoPlay = false;
break;
case 2 : // 界面切换中
isAutoPlay = true;
break;
case 0 : // 滑动结束,即切换完毕或者加载完毕
// 当前为最后一张,此时从右向左滑,则切换到第一张
if ( viewPager .getCurrentItem() == viewPager .getAdapter().getCount() - 1 && ! isAutoPlay ) {
viewPager .setCurrentItem( 0 ) ;
}
// 当前为第一张,此时从左向右滑,则切换到最后一张
else if ( viewPager .getCurrentItem() == 0 && ! isAutoPlay ) {
viewPager .setCurrentItem( viewPager .getAdapter().getCount() - 1 ) ;
}
break;
}
}

@Override
public void onPageScrolled ( int arg0 , float arg1 , int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onPageSelected ( int pos) {
// TODO Auto-generated method stub

currentItem = pos ;
for ( int i= 0 ; i < dotViewsList .size() ; i++){
if (i == pos){
((View) dotViewsList .get(pos)).setBackgroundResource(R.drawable. dotshape ) ;
} else {
((View) dotViewsList .get(i)).setBackgroundResource(R.drawable. dotshape_second ) ;
}
}
}

}

/**
*执行轮播图切换任务
* @author caizhiming
*/
private class SlideShowTask implements Runnable{

@Override
public void run () {
// TODO Auto-generated method stub
synchronized ( viewPager ) {
currentItem = ( currentItem + 1 )% imageViewsList .size() ;
handler .obtainMessage().sendToTarget() ;
}
}

}
/**
* 销毁ImageView资源,回收内存
* @author caizhiming
*/
private void destoryBitmaps () {

for ( int i = 0 ; i < IMAGE_COUNT ; i++) {
ImageView imageView = imageViewsList .get(i) ;
Drawable drawable = imageView.getDrawable() ;
if (drawable != null ) {
//解除drawable对view的引用
drawable.setCallback( null ) ;
}
}
}

} 欢迎指正,面临毕业要学的东西很多。我们可以共同进步嘛。
【仿b站demo(功能实现篇)】

    推荐阅读