初级控件
这些控件主要有TextView
Button
EditText
ImageView
RadioButton
Checkbox
等,这些控件都比较简单。所有的控件都有通用属性,通过设置这些属性值,就能对控件进行修改。
高级控件
这些控件主要有ListView GridView RadioGroup WebView
等。
ListView
要实现ListView
必须实现Adapter
。
MyBaseAdapter.java
package mylistview.iamac.wang.mylistview;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public abstract class MyBaseAdapter<T> extends BaseAdapter {
private Context context;
private int resource;
private List<T> list;
public MyBaseAdapter(Context context, int resource) {
this(context, resource, new ArrayList<T>());
}
public MyBaseAdapter(Context context, @LayoutRes int resource, @NonNull T[] objects){
this(context, resource, new ArrayList<>(Arrays.asList(objects)));
}
public MyBaseAdapter(Context context, int resource, @NonNull List<T> list) {
this.context = context;
this.resource = resource;
this.list = list;
}
public void add(T object){
list.add(object);
/**important*/
notifyDataSetChanged();
}
public void remove(T object){
list.remove(object);
notifyDataSetChanged();
}
@Override
public int getCount() {
return list.size();
}
@Override
public T getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null){
convertView = LayoutInflater.from(context).inflate(resource,null);
}
setView(position,convertView,parent);
return convertView;
}
public abstract void setView(int position, View convertView, ViewGroup parent);
}
MainActivity.java
package mylistview.iamac.wang.mylistview;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.regex.MatchResult;
public class MainActivity extends Activity implements AdapterView.OnItemClickListener {
private MyBaseAdapter<ListData> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListData[] data = new ListData[]{
new ListData("Tom", new Date(),R.drawable.brush),
new ListData("Jack", new Date(),R.drawable.clock),
new ListData("Lucky", new Date(String.valueOf(new SimpleDateFormat("yyyy-MM-dd").parse("2015-05-06", new ParsePosition(0)))),R.drawable.globe)
};
/**Using System ListView
*
* adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
* adapter.add("one");
* adapter.add("two");
*
*/
/**Using Custom ListView
*/
adapter = new MyBaseAdapter<ListData>(this,R.layout.listview,data) {
@Override
public void setView(int position, View convertView, ViewGroup parent) {
TextView tv = (TextView) convertView.findViewById(R.id.textView);
TextView tv2 = (TextView) convertView.findViewById(R.id.textView2);
ImageView im = (ImageView) convertView.findViewById(R.id.imageView);
tv.setText(getItem(position).getName());
tv2.setText(getItem(position).getData().toString());
im.setImageResource(getItem(position).getId());
}
};
/**Using Custom ListView
*/
ListView lv = (ListView) findViewById(R.id.listView);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.add(new ListData("Random"+hashCode(), new Date(),R.drawable.common_full_open_on_phone));
}
});
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(this, adapter.getItem(position).getName() + "\n" + adapter.getItem(position).getData().toString(), Toast.LENGTH_SHORT).show();
}
}
WebView
基本使用
package com.iamac.tryapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.TextView;
public class NewPage extends Activity {
private WebView webview;
private ProgressBar pb;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.new_page);
init();
webview.loadUrl(getIntent().getData().toString());
}
private void init(){
pb = (ProgressBar)findViewById(R.id.progressBar1);
webview = (WebView) findViewById(R.id.webView1);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webview.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
//get the newProgress and refresh progress bar
pb.setProgress(newProgress);
if(pb.getProgress()==100){
pb.setVisibility(ProgressBar.GONE);
}else{
pb.setVisibility(ProgressBar.VISIBLE);
}
}
});
webview.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
class MyDownloadListenter implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype, long contentLength) {
new DownloadThread(url).start();
}
}
webview.setDownloadListener(new MyDownloadListenter());
}
}
通过WebView下载
- 自定义下载线程
package com.iamac.tryapp;
import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import static java.lang.System.currentTimeMillis;
public class DownloadThread extends Thread {
public String url;
public DownloadThread(String url) {
this.url = url;
}
@Override
public void run() {
super.run();
try {
URL murl = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection)murl.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
InputStream in = conn.getInputStream();
File path, dlFile;
FileOutputStream out = null;
if(Environment.getExternalStorageState() == Environment.MEDIA_UNMOUNTED){
path = Environment.getExternalStorageDirectory();
dlFile = new File(path,"new"+ currentTimeMillis());
out = new FileOutputStream(dlFile);
}
byte[] buffer = new byte[1024 * 4];
int len = 0;
while ( (len = in.read(buffer))!= 0 ){
}
if(out != null) out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 启动系统下载模块
class MyDownloadListenter implements DownloadListener{
@Override
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype, long contentLength) {
Uri uri = Uri.parse(url);
· Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
Layout
常用主要有 LinearLayout RelativeLayout GridLayout FrameLayout Fragment
。前面几个都比较简单,重点了解Fragment
。
Fragment
package iamac.wang.myfragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
public class MainActivity extends AppCompatActivity implements FragmentOne.MyOnItemClick {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setDisplayOptions(android.support.v7.app.ActionBar.DISPLAY_SHOW_TITLE);
}
@Override
public void OnClick(String name) {
FragmentTwo fragmentTwo = (FragmentTwo) getFragmentManager().findFragmentById(R.id.fragment2);
fragmentTwo.update(name);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.mymenu,menu);
return true;
}
}
package iamac.wang.myfragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class FragmentTwo extends Fragment {
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_two,container);
return view;
}
public void update(String value){
EditText editText;
editText = ((EditText)(view.findViewById(R.id.editText)));
editText.append(value+"\n");
}
}
package iamac.wang.myfragment;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class FragmentOne extends Fragment implements AdapterView.OnItemClickListener {
private Activity aty;
private ArrayAdapter<String> adapter;
private String[] strings = {
"英语","数学", "语文","物理"
};
public interface MyOnItemClick{
void OnClick(String name);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = LayoutInflater.from(aty).inflate(R.layout.fragment_one,container);
ListView lv = (ListView) view.findViewById(R.id.listView);
adapter = new ArrayAdapter<>(aty,android.R.layout.simple_list_item_1,strings);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(getActivity() instanceof MyOnItemClick){
aty = getActivity();
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (aty != null)
((MyOnItemClick)aty).OnClick(adapter.getItem(position));
}
}
自定义View
实现View的子类,重载OnDraw(Canvas canvas)
方法。
Canvas绘图
Canvas
提供了如下函数:
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
Draw the specified bitmap, scaling/translating automatically to fill the destination rectangle.
drawPicture(Picture picture, Rect dst)
Draw the picture, stretched to fit into the dst rectangle.
drawCircle(float cx, float cy, float radius, Paint paint)
Draw the specified circle using the specified paint.
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
Draw a line segment with the specified start and stop x,y coordinates, using the specified paint.
drawRect(Rect r, Paint paint)
Draw the specified Rect using the specified Paint.
drawText(String text, float x, float y, Paint paint)
Draw the text, with origin at (x,y), using the specified paint.
rotate(float degrees, float px, float py)
Preconcat the current matrix with the specified rotation.
自定义View的使用
- 通过Java代码添加
- 在布局文件中使用,使用方法为:<com.iamac.chess.Mychess … />
实例
package com.sixchess.sixchess.activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.sixchess.sixchess.R;
import com.sixchess.sixchess.Solve;
import static com.sixchess.sixchess.Solve.blackLeft;
import static com.sixchess.sixchess.Solve.chessManager;
import static com.sixchess.sixchess.Solve.isBlack;
import static com.sixchess.sixchess.Solve.isPlaying;
import static com.sixchess.sixchess.Solve.selectedChess;
import static com.sixchess.sixchess.Solve.whiteLeft;
import static com.sixchess.sixchess.Solve.xStep;
import static com.sixchess.sixchess.Solve.yStep;
import static java.lang.Math.floor;
public class ChessBoard extends View {
public static Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private MainActivity context = null;
DisplayMetrics dm;
//Chess Board 参数
private int boardStep;
private int boardStart = 100;
private int chessLen;
public ChessBoard(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = (MainActivity) context;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//得到屏幕信息并计算棋盘以及棋子信息
dm = context.getResources().getDisplayMetrics();
boardStep = ( dm.widthPixels - 200 ) / 3;
Log.v("Screen :","W :" + dm.widthPixels + " H :" + dm.heightPixels);
if(dm.widthPixels > dm.heightPixels){
boardStep = ( dm.heightPixels - 200 ) / 3;
}
chessLen = (int) (0.4 * boardStep);
//设置View的大小
setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,boardStart * 2 + boardStep * 3));
//绘制棋盘
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
for(int i= boardStart ;i <= boardStep * 2 + boardStart ;i += boardStep ){
for(int j= boardStart ;j <= boardStep * 2 + boardStart;j += boardStep){
canvas.drawRect(i,j,i+boardStep,j+boardStep,mPaint);
}
}
//绘制选框
int x = xStep * boardStep + boardStart - chessLen / 2;
int y = yStep * boardStep + boardStart - chessLen / 2;
mPaint.setColor(Color.RED);
canvas.drawRect(x,y, x + chessLen, y + chessLen, mPaint);
//绘制棋子
blackLeft = 0; whiteLeft = 0;
for(int i = 0; i < 4; i++){
for(int j = 0 ; j < 4;j++){
int xx = j * boardStep + boardStart - chessLen / 2;
int yy = i * boardStep + boardStart - chessLen / 2;
try {
if(chessManager[i][j] == 1){
blackLeft++;
canvas.drawBitmap(context.getChessBlack() , null , new Rect(xx,yy ,xx + chessLen, yy + chessLen), mPaint);
}
if(chessManager[i][j] == -1) {
whiteLeft++;
canvas.drawBitmap(context.getChessWhite() , null , new Rect(xx,yy ,xx + chessLen, yy + chessLen), mPaint);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
//游戏是否结束
if(whiteLeft == 0 || blackLeft == 0 || whiteLeft == 1 && blackLeft == 1 ){
if(whiteLeft == 0 )isPlaying = -1;
if(blackLeft == 0) isPlaying = -2;
if(whiteLeft == 1 && blackLeft == 1) isPlaying = -3;
}else {
Log.v("moveable:",( isBlack == 1 ? "black " : "white " )+isMoveable());
if(!isMoveable()) isPlaying = (isBlack == 1 ? -2 : -1 ) ;
}
//根据游戏状态码做出相应动作
String res = "";
switch (isPlaying){
case -1:
res = context.getResources().getString(R.string.winner_black);
break;
case -2:
res = context.getResources().getString(R.string.winner_white);
break;
case -3:
res = context.getResources().getString(R.string.winner_tied);
break;
}
if(res != "") {
Toast.makeText(this.context, res, Toast.LENGTH_SHORT).show();
((MainActivity) context).getThread().pauseThread();
}
}
public int onClick(float x, float y) {
xStep = floatToInt((x - boardStart) / boardStep);
yStep = floatToInt((y - boardStart) / boardStep);
Log.v("量化坐标:","("+ xStep + "," + yStep + ")");
//当前坐标有效且 (去选棋子或者 已选中旗子去选择下个位置)
if(xStep > -1 && yStep > -1 && xStep < 4 && yStep < 4 && (chessManager[yStep][xStep] == isBlack || (chessManager[yStep][xStep] == 0 && selectedChess.isSelected && canReachable(xStep,yStep))) ){
Solve.sendXY(xStep, yStep);
invalidate();
}
return 0;
}
private boolean canReachable(int xStep, int yStep) {
int dir[][] = {{0,1},{1,0},{0,-1},{-1,0}};
for(int i = 0;i < 4; i++){
int x = selectedChess.xPos + dir[i][0];
int y = selectedChess.yPos + dir[i][1];
if(x == xStep && yStep == y) return true;
}
return false;
}
private boolean isMoveable(){
for(int i = 0; i < 4; i++){
for(int j = 0 ; j < 4;j++){
if(chessManager[i][j] == isBlack){
int dir[][] = {{0,1},{1,0},{0,-1},{-1,0}};
for(int k = 0; k < 4; k++){
int xx = i + dir[k][0];
int yy = j + dir[k][1];
if(xx > -1 && yy > -1 && xx < 4 && yy < 4 && chessManager[xx][yy] == 0) return true;
}
}
}
}
return false;
}
public int floatToInt(float x){
int res = -1;
Log.v("x - floor(x)", "" + (x - floor(x) + "?" + (1.0 * chessLen / 2 / boardStep) + "?" + (1 - 1.0 * chessLen / 2 / boardStep)));
if( x - floor(x) <= 1.0 * chessLen / 2 / boardStep ) res = (int)floor(x);
else if(x - floor(x) >= 1 - 1.0 * chessLen / 2 / boardStep ) res = (int)floor(x) + 1;
return res;
}
}