20189200余超 2018-2019-2 移动平台应用开发实践第八周作业

20189200余超 2018-2019-2 移动平台应用开发实践第八周作业

ListView

1.自定义BaseAdapter,然后绑定ListView的最简单例子
先看看我们要实现的效果图:

一个很简单的ListView,自己写下Item,然后加载点数据这样~ 下面贴下关键代码:

Animal.java:

public class Animal {
    private String aName;
    private String aSpeak;
    private int aIcon;

    public Animal() {
    }

    public Animal(String aName, String aSpeak, int aIcon) {
        this.aName = aName;
        this.aSpeak = aSpeak;
        this.aIcon = aIcon;
    }

    public String getaName() {
        return aName;
    }

    public String getaSpeak() {
        return aSpeak;
    }

    public int getaIcon() {
        return aIcon;
    }

    public void setaName(String aName) {
        this.aName = aName;
    }

    public void setaSpeak(String aSpeak) {
        this.aSpeak = aSpeak;
    }

    public void setaIcon(int aIcon) {
        this.aIcon = aIcon;
    }
}

AnimalAdapter.java:自定义的BaseAdapter:

public class AnimalAdapter extends BaseAdapter {

    private LinkedList<Animal> mData;
    private Context mContext;

    public AnimalAdapter(LinkedList<Animal> mData, Context mContext) {
        this.mData = mData;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
        ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
        TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
        TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
        img_icon.setBackgroundResource(mData.get(position).getaIcon());
        txt_aName.setText(mData.get(position).getaName());
        txt_aSpeak.setText(mData.get(position).getaSpeak());
        return convertView;
    }
}

最后是MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private List<Animal> mData = null;
    private Context mContext;
    private AnimalAdapter mAdapter = null;
    private ListView list_animal;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        list_animal = (ListView) findViewById(R.id.list_animal);
        mData = new LinkedList<Animal>();
        mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog));
        mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow));
        mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck));
        mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish));
        mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse));
        mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext);
        list_animal.setAdapter(mAdapter);
    }

}

好的,自定义BaseAdapter以及完成数据绑定就是这么简单~
别问我拿示例的代码,刚开始学就会写出这些代码,我只是演示下流程,让大家熟悉 熟悉而已另外,也是为下面的属性验证做准备
2.表头表尾分割线的设置:
listview作为一个列表控件,他和普通的列表一样,可以自己设置表头与表尾: 以及分割线,可供我们设置的属性如下:

footerDividersEnabled:是否在footerView(表尾)前绘制一个分隔条,默认为true
headerDividersEnabled:是否在headerView(表头)前绘制一个分隔条,默认为true
divider:设置分隔条,可以用颜色分割,也可以用drawable资源分割
dividerHeight:设置分隔条的高度
翻遍了了API发现并没有可以直接设置ListView表头或者表尾的属性,只能在Java中写代码 进行设置了,可供我们调用的方法如下:

addHeaderView(View v):添加headView(表头),括号中的参数是一个View对象
addFooterView(View v):添加footerView(表尾),括号中的参数是一个View对象
addHeaderView(headView, null, false):和前面的区别:设置Header是否可以被选中
addFooterView(View,view,false):同上
对了,使用这个addHeaderView方法必须放在listview.setAdapter前面,否则会报错。

代码实现:
先编写下表头与表尾的布局:
view_header.xml(表头),表尾一样,就不贴了:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:textSize="18sp"
        android:text="表头"
        android:gravity="center"
        android:background="#43BBEB"
        android:textColor="#FFFFFF"/>
</LinearLayout>

MainActivty.java:

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{

    private List<Animal> mData = null;
    private Context mContext;
    private AnimalAdapter mAdapter = null;
    private ListView list_animal;
    private LinearLayout ly_content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        list_animal = (ListView) findViewById(R.id.list_animal);
        //动态加载顶部View和底部View
        final LayoutInflater inflater = LayoutInflater.from(this);
        View headView = inflater.inflate(R.layout.view_header, null, false);
        View footView = inflater.inflate(R.layout.view_footer, null, false);

        mData = new LinkedList<Animal>();
        mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog));
        mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow));
        mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck));
        mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish));
        mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse));
        mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext);
        //添加表头和表尾需要写在setAdapter方法调用之前!!!
        list_animal.addHeaderView(headView);
        list_animal.addFooterView(footView);

        list_animal.setAdapter(mAdapter);
        list_animal.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(mContext,"你点击了第" + position + "项",Toast.LENGTH_SHORT).show();
    }
}

好的,代码还是比较简单的,从上面我们看出来一个要注意的问题,就是:
添加表头表尾后,我们发现positon是从表头开始算的,就是你添加的第一个数据本来的 postion 是 0,但是此时却变成了 1,因为表头也算!!

GridView

GridView与ListView的用法基本一致,不同的只是布局。当我们打开手机,应用会以宫格显示,那就是GridView。
以代码形式展示给大家,适配器使用SimpleAdapter,熟悉了适配器的用法,就只需要注意几个GridView的属性即可。
Activity类

public class MainActivity extends Activity {
    private GridView gridView;
    private List<Map<String, Object>> dataList;
    private SimpleAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gridView = (GridView) findViewById(R.id.gridview);
        //初始化数据
        initData();

        String[] from={"img","text"};

        int[] to={R.id.img,R.id.text};

        adapter=new SimpleAdapter(this, dataList, R.layout.gridview_item, from, to);

        gridView.setAdapter(adapter);

        gridView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
            AlertDialog.Builder builder= new AlertDialog.Builder(MainActivity.this);
            builder.setTitle("提示").setMessage(dataList.get(arg2).get("text").toString()).create().show();
            }
        });
    }

    void initData() {
        //图标
        int icno[] = { R.drawable.i1, R.drawable.i2, R.drawable.i3,
                R.drawable.i4, R.drawable.i5, R.drawable.i6, R.drawable.i7,
                R.drawable.i8, R.drawable.i9, R.drawable.i10, R.drawable.i11, R.drawable.i12 };
        //图标下的文字
        String name[]={"时钟","信号","宝箱","秒钟","大象","FF","记事本","书签","印象","商店","主题","迅雷"};
        dataList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i <icno.length; i++) {
            Map<String, Object> map=new HashMap<String, Object>();
            map.put("img", icno[i]);
            map.put("text",name[i]);
            dataList.add(map);
        }
    }

}
**GridView主布局文件activity_main.xml**
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000"
    tools:context="com.example.l7.MainActivity" >
    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnWidth="80dp"
        android:stretchMode="spacingWidthUniform"
        android:numColumns="3" 
         />
</LinearLayout>

列表项布局gridview_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginTop="10dp" 
        android:src="@drawable/ic_launcher" />
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp" 
        android:layout_gravity="center"
        android:textColor="#FFF"
        android:text="文字"
        />

</LinearLayout>

效果图

样式和主题

样式是指为 View 或窗口指定外观和格式的属性集合。样式可以指定高度、填充、字体颜色、字号、背景色等许多属性。 样式是在与指定布局的 XML 不同的 XML 资源中进行定义。
Android 中的样式与网页设计中层叠样式表的原理类似 — 您可以通过它将设计与内容分离。
例如,通过使用样式,您可以将以下布局 XML:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#00FF00"
    android:typeface="monospace"
    android:text="@string/hello" />
简化成这个样子:

<TextView
    style="@style/CodeFont"
    android:text="@string/hello" />

布局 XML 中所有与样式有关的属性都已移除,并置于一个名为 CodeFont 的样式定义内,然后通过 style 属性加以应用。 您会在下文中看到对该样式的定义。
主题是指对整个 Activity 或应用而不是对单个 View(如上例所示)应用的样式。 以主题形式应用样式时,Activity 或应用中的每个视图都将应用其支持的每个样式属性。 例如,您可以 Activity 主题形式应用同一 CodeFont 样式,之后该 Activity 内的所有文本都将具有绿色固定宽度字体。

定义样式
要创建一组样式,请在您的项目的 res/values/ 目录中保存一个 XML 文件。 可任意指定该 XML 文件的名称,但它必须使用 .xml 扩展名,并且必须保存在 res/values/ 文件夹内。
该 XML 文件的根节点必须resources。
对于您想创建的每个样式,向该文件添加一个 style 元素,该元素带有对样式进行唯一标识的 name 属性(该属性为必需属性)。然后为该样式的每个属性添加一个 item 元素,该元素带有声明样式属性以及属性值的 name(该属性为必需属性)。 根据样式属性,item 的值可以是关键字字符串、十六进制颜色值、对另一资源类型的引用或其他值。以下是一个包含单个样式的示例文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="CodeFont" parent="@android:style/TextAppearance.Medium">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textColor">#00FF00</item>
        <item name="android:typeface">monospace</item>
    </style>
</resources>
resources 

元素的每个子项都会在编译时转换成一个应用资源对象,该对象可由 style>元素的 name 属性中的值引用。 可从 XML 布局以 @style/CodeFont 形式引用该示例样式(如上文引言中所示)。
style 元素中的 parent 属性是可选属性,它指定应作为此样式所继承属性来源的另一样式的资源 ID。 如果愿意,您可在随后替换这些继承的样式属性。
切记,在 XML 中定义您想用作 Activity 或应用主题的样式与定义视图样式的方法完全相同。 诸如上文所定义的样式可作为单个视图的样式加以应用,也可作为整个 Activity 或应用的主题加以应用。 后文将阐述如何为单个视图应用样式或如何以应用主题形式应用样式。
设置样式的方法有两种:

如果是对单个视图应用样式,请为布局 XML 中的 View 元素添加 style 属性。
或者,如果是对整个 Activity 或应用来应用样式,请为 Android 清单中的 activity 或 application 元素添加 android:theme 属性。
当您对布局中的单个 View 应用样式时,该样式定义的属性只应用于该 View。 如果对 ViewGroup 应用样式,子 View 元素将不会继承样式属性 — 只有被您直接应用样式的元素才会应用其属性。 不过,您可以通过以主题形式应用样式,使所应用的样式作用于所有 View 元素。

要以主题形式应用样式定义,您必须在 Android 清单中将样式应用于 Activity 或应用。 如果您这样做,Activity 或应用内的每个 View 都将应用其支持的每个属性。 例如,如果您对某个 Activity 应用前面示例中的 CodeFont 样式,则所有支持这些文本样式属性的 View 元素也会应用这些属性。 任何不支持这些属性的 View 都会忽略这些属性。 如果某个 View 仅支持部分属性,将只应用这些属性。

对视图应用样式

为 XML 布局中的视图设置样式的方法如下:

<
TextView
    style="@style/CodeFont"
    android:text="@string/hello" />

现在该 TextView 将按照名为 CodeFont 的样式的定义设置样式(请参阅上文定义样式中的示例)。

注:style 属性不使用 android: 命名空间前缀。

对 Activity 或应用应用主题
要为您的应用的所有 Activity 设置主题,请打开 AndroidManifest.xml 文件并application 标记,在其中加入带样式名称的 android:theme 属性。 例如:

如果您只想对应用中的一个 Activity 应用主题,则改为给 标记添加 android:theme 属性。

正如 Android 提供了其他内建资源一样,有许多预定义主题可供您使用,可免于自行编写。 例如,您可以使用 Dialog 主题,为您的 Activity 赋予类似对话框的外观:

或者,如果您希望背景是透明的,则可使用 Translucent 主题:

<activity android:theme="@android:style/Theme.Translucent">
如果您喜欢某个主题,但想做些调整,只需将该主题添加为您的自定义主题的 parent。 例如,您可以像下面这样对传统明亮主题进行修改,使用您自己的颜色:
<color name="custom_theme_color">#b0b0ff</color>
<style name="CustomTheme" parent="android:Theme.Light">
    <item name="android:windowBackground">@color/custom_theme_color</item>
    <item name="android:colorBackground">@color/custom_theme_color</item>
</style>

(请注意,此处颜色需要以单独资源形式提供,因为 android:windowBackground 属性仅支持对另一资源的引用;不同于 android:colorBackground,无法为其提供颜色字面量。)

现在,在 Android 清单内使用 CustomTheme 替代 Theme.Light:

根据平台版本选择主题
新版本的 Android 可为应用提供更多主题,您可能希望在这些平台上运行时可以使用这些新增主题,同时仍可兼容旧版本。 您可以通过自定义主题来实现这一目的,该主题根据平台版本利用资源选择在不同父主题之间切换。

位图处理

图片的处理包括以下:

1, 缩放

2, 倾斜

3, 旋转

4, 缩放+

5, 平移

6, 镜像

代码如下:

package com.mike.activity; 
import java.io.FileNotFoundException; 
import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.BitmapFactory.Options; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.net.Uri; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Display; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.ImageView; 
 
public class ImageDemoActivity extends Activity implements OnClickListener { 
    /** Called when the activity is first created. */ 
 
    public static String TAG = "IMAGE"; 
    public static int REQUEST_CODE = 0; 
    private ImageView mImageShow; 
    private ImageView mImageAltered; 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
 
        Button p_w_picpathSelectBtn = (Button) findViewById(R.id.p_w_picpathSelectBtn); 
        mImageShow = (ImageView) findViewById(R.id.p_w_picpathShow); 
        mImageAltered = (ImageView) findViewById(R.id.p_w_picpathAltered); 
        p_w_picpathSelectBtn.setOnClickListener(this); 
    } 
 
    public void onClick(View v) { 
        // TODO Auto-generated method stub 
        Intent intent = new Intent(Intent.ACTION_PICK, 
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 启动照片Gallery 
        startActivityForResult(intent, 0); 
    } 
 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, 
            Intent intent) { 
        // TODO Auto-generated method stub 
        super.onActivityResult(requestCode, resultCode, intent); 
 
        if (resultCode == RESULT_OK) {// 操作成功 
            Uri imgFileUri = intent.getData();// 获得所选照片的信息 
            Log.d(TAG, "imgFileUri is :" + imgFileUri); 
            // 由于返回的图像可能太大而无法完全加载到内存中。系统有限制,需要处理。 
            Display currentDisplay = getWindowManager().getDefaultDisplay(); 
            int defaultHeight = currentDisplay.getHeight(); 
            int defaultWidth = currentDisplay.getWidth(); 
 
            BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options(); 
            bitmapFactoryOptions.inJustDecodeBounds = false;// /只是为获取原始图片的尺寸,而不返回Bitmap对象 
            // 注上:If set to true, the decoder will return null (no bitmap), but 
            // the out... fields will still be set, 
            // allowing the caller to query the bitmap without having to 
            // allocate the memory for its pixels 
            try { 
                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() 
                        .openInputStream(imgFileUri), null, 
                        bitmapFactoryOptions); 
                int outHeight = bitmapFactoryOptions.outHeight; 
                int outWidth = bitmapFactoryOptions.outWidth; 
                int heightRatio = (int) Math.ceil((float) outHeight 
                        / defaultHeight); 
                int widthRatio = (int) Math.ceil((float) outWidth 
                        / defaultWidth); 
 
                if (heightRatio > 1 || widthRatio > 1) { 
                    if (heightRatio > widthRatio) { 
                        bitmapFactoryOptions.inSampleSize = heightRatio; 
                    } else { 
                        bitmapFactoryOptions.inSampleSize = widthRatio; 
                    } 
                } 
 
                bitmapFactoryOptions.inJustDecodeBounds = false; 
                bitmap = BitmapFactory.decodeStream(getContentResolver() 
                        .openInputStream(imgFileUri), null, 
                        bitmapFactoryOptions); 
 
                mImageShow.setImageBitmap(bitmap); 
 
                // /* 
                // * 在位图上绘制位图 
                // */ 
                // 
                // Bitmap bitmapAltered = Bitmap.createBitmap(bitmap.getWidth(), 
                // bitmap.getHeight(), bitmap.getConfig()); 
                // 
                // Canvas canvas = new 
                // Canvas(bitmapAltered);//bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来 
                // 
                // 
                // Paint paint = new Paint(); 
                // 
                // canvas.drawBitmap(bitmap, 0, 0, paint);//绘制的图片和之前的一模一样 
                // 
                // mImageAltered.setImageBitmap(bitmapAltered); 
 
                /* 
                 * 使用矩阵 
                 */ 
 
                Bitmap bitmapAltered = Bitmap.createBitmap(bitmap.getWidth(), 
                        bitmap.getHeight(), bitmap.getConfig());// 缺点是限定画布大小,处理后的图片可能被截断,可引入矩阵构造方法,动态设定画布大小 
                Canvas canvas = new Canvas(bitmapAltered);// bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来, 
                Paint paint = new Paint(); 
 
                Matrix matrix = new Matrix(); 
 
                // 1:缩放 
                // matrix.setValues(new float[] {//涉及线性代数的知识,可以翻翻相乘的基础知识 
                // 1,0,0,//算出x的值 
                // 0,1,0,//算出y的值 
                // 0,0,1//二维图用不到 
                // }); 
 
                // 2:倾斜 
                // matrix.setValues(new float[] {//涉及线性代数的知识,可以翻翻相乘的基础知识 
                // 1,.5f,0,//算出x的值,x,y值相关 
                // 0,1,0,//算出y的值 
                // 0,0,1//二维图用不到 
                // }); 
 
                // 3:旋转 
                // matrix.setRotate(45);//设置旋转角度,(0,0)点,顺时针旋转45度 
 
                // 4,缩放plus:使用Matrix类方法//需要修改画布宽度>1.5倍* 原始宽度 
                // matrix.setScale(1.5f, 1); 
 
                // 5,平移 
                // matrix.setTranslate(10, 0); 
 
                // 6,镜像 
                // eg1:x轴镜像 
                // matrix.setScale(-1, 1);//向左绘制,原始图片沿y轴对称 
                // matrix.postTranslate(bitmap.getWidth(), 0);//注意是post即后移动 
                // eg2:y轴镜像 
                matrix.setScale(1, -1);// 向上绘制,原始图片沿x轴对称,图像在第四象限 
                matrix.postTranslate(0, bitmap.getHeight());// 注意是post即后移动 
                 
                 
                //~optimize~因为指定画布大小bitmapAltered,所以处理后的图片可能被截断,可以通过矩阵动态改变bitmapAltered大小 
                //eg: matrix.setRotate(degrees, px, py) 
                //bitmapAltered = Bitmap.createBitmap(source, x, y, width, height, m, filter);//显然矩阵影响其大小 
 
                // 
 
                // 注:for more details :Wikipedia Transformation Matrix 
                // http://en.wikipedia.org/wiki/Transformation_matrix 
 
                canvas.drawBitmap(bitmap, matrix, paint);// 绘制的图片和之前的一模一样 
 
                mImageAltered.setImageBitmap(bitmapAltered); 
 
            } catch (FileNotFoundException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
 
        } 
    } 
}  

原文地址:https://www.cnblogs.com/yuchao123/p/10726385.html