android学习——使用TableLayout动态生成表格,并为tablerow中的列添加点击监听
16lz
2021-01-25
在android中实现表格的形式主要有三种:一是Gridview ,实现网状布局,但是它的行和列的大小是定的;二是ListView,这在实际应用中应该用的最多的,它可以通过Layout_weight 属性,实现不同的尺寸列显示,但是当设定Layout_weight值后,列的尺寸也是固定了的。三是TableLayout,这是文档中专门用于表格显示的布局,通过 android:shrinkColumns (自动缩进列长度)和 android:stretchColumns (自动延伸列长度)属性可以实现列尺寸的自动缩进和延伸。
下面的例子也是结合了很多参考内容写出来的,在这只想和大家分享,希望能帮到有需要的人。
首先,说说背景吧,最近在做毕设,这个例子也就是其中的一个模块——课程查询。该模块提供两种功能,一个是按学院名查询课程,另一个是按课程名查询课程。并将查询的结构显示在TableLayout布局中,TableLayout的使用可以找些博文,有些讲的非常清楚,在这我就不累赘。先贴一段布局文件的代码,没什么好解释的,都是些简单的布局,所以比较难看。
这里要解释下,spinner的用法,应该很容易找到相关的知识,所以就不多说了。主要提下这里的tablerow,它的显示是通过shape文件修改了的, kccx_course_table TableLayout 中将自动生成的tablerow也是通过shape文件实现边框效果的。效果不是很好看,但大家可以自己摸索下,实现比较漂亮的效果。在这个例子中,定义了两个shape文件,一个用于修改显示 TableLayout布局中各列的 标题的,另一个用于显示自动生成的tablerow,其中的一个 shape文件如下:
现在看看代码吧,
在 MyTask1类中, doInBackground()方法主要是从webservice获得集合 resultList,hk是负责与webservice交互的 KCInteractiveWebHelper 类的对象。这里主要讲下 onPostExecute(String result)方法里面的内容: 首先记得加上这一句: courseTable .removeAllViewsInLayout();要不然显示的效果会是这样
他会把上一次查询结果也显示出来。同时,这里也就要解释下前面的,为什么添加 kccx_course_table TableLayout , 如果不添加的话,在执行 removeAllViewsInLayout()方法时会将 移除掉。增加一个TableLayout 虽然会使得标题和显示的内容尺寸大小不一样,但也只能退而求其次了。 还有些内容就在代码中注释, ParamFromCodeDialogFrag是继承了DialogFragment的类,它主要用于显示提示信息,在这里用于显示课程简介。它的具体实现请参考 这里 ,只是要改变下参数的类型。 最后贴几张效果图
下面的例子也是结合了很多参考内容写出来的,在这只想和大家分享,希望能帮到有需要的人。
首先,说说背景吧,最近在做毕设,这个例子也就是其中的一个模块——课程查询。该模块提供两种功能,一个是按学院名查询课程,另一个是按课程名查询课程。并将查询的结构显示在TableLayout布局中,TableLayout的使用可以找些博文,有些讲的非常清楚,在这我就不累赘。先贴一段布局文件的代码,没什么好解释的,都是些简单的布局,所以比较难看。
<?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:background="@color/chat_background" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/kechengchaxun_anxueyuanchaxun" android:textSize="18sp" /> <Spinner android:id="@+id/kccx_spinner1" android:layout_width="200dip" android:layout_height="50dp" /> <Button android:id="@+id/kccx_chaxun1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/kechengchaxun_chaxun" /> </LinearLayout> <View android:layout_width="fill_parent" android:layout_height="10.0dip" android:background="@drawable/fengeview" > </View> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/kechengchaxun_ankechengchaxun" android:textSize="18sp" /> <EditText android:id="@+id/kccx_course_name" android:layout_width="200dip" android:layout_height="wrap_content" android:inputType="textCapWords" /> <Button android:id="@+id/kccx_chaxun2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/kechengchaxun_chaxun" /> </LinearLayout> <View android:layout_width="fill_parent" android:layout_height="20.0dip" android:background="@drawable/fengeview" > </View> <ScrollView android:layout_width="fill_parent" android:layout_height="match_parent" > <TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:shrinkColumns="0" android:stretchColumns="*" > <TableRow> <TextView android:layout_height="wrap_content" android:background="@drawable/table_title_shape" android:padding="2.5dp" android:text="@string/kechengchaxun_xueyuan" /> <TextView android:layout_height="wrap_content" android:background="@drawable/table_title_shape" android:padding="2.5dp" android:text="@string/kechengchaxun_kechengming" /> <TextView android:layout_height="wrap_content" android:background="@drawable/table_title_shape" android:padding="2.5dp" android:text="@string/kechengchaxun_xuefen" /> <TextView android:layout_height="wrap_content" android:background="@drawable/table_title_shape" android:padding="2.5dp" android:text="@string/kechengchaxun_xianxiukecheng" /> <TextView android:layout_height="wrap_content" android:background="@drawable/table_title_shape" android:padding="2.5dp" android:text="@string/kechengchaxun_kaikexueqi" /> </TableRow> <TableLayout android:id="@+id/kccx_course_table" android:stretchColumns="*" android:shrinkColumns="0"> </TableLayout> </TableLayout> </ScrollView></LinearLayout>在 < TableLayout> </ TableLayout >中嵌套了一个id为 kccx_course_table 的 TableLayout,自动生成的tablerow将显示在此 TableLayout。至于为什么在这多添加个 TableLayout,而不直接用第一个 TableLayout, 后面会解释,在这只是一种解决办法,可能还有更好的我没想到,知道的希望能告诉下。布局的效果如下:
这里要解释下,spinner的用法,应该很容易找到相关的知识,所以就不多说了。主要提下这里的tablerow,它的显示是通过shape文件修改了的, kccx_course_table TableLayout 中将自动生成的tablerow也是通过shape文件实现边框效果的。效果不是很好看,但大家可以自己摸索下,实现比较漂亮的效果。在这个例子中,定义了两个shape文件,一个用于修改显示 TableLayout布局中各列的 标题的,另一个用于显示自动生成的tablerow,其中的一个 shape文件如下:
<?xml version="1.0" encoding= "utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient android:startColor= "#ff7fa4c9" android:endColor= "#ff7fa4c9" android:angle= "0"/> <padding android:left ="7dp" android:top= "7dp" android:right= "7dp" android:bottom= "7dp" /> <corners android:radius ="8dp" /></shape>
现在看看代码吧,
import java.util.ArrayList;import java.util.List;import com.example.bean.Course;import com.example.dialogs.ParamFromCodeDialogFrag;import com.example.mobileelectivesystem.chakankecheng.KCInteractiveWebHelper;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemSelectedListener;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.Spinner;import android.widget.TableLayout;import android.widget.TableRow;import android.widget.TextView;import android.widget.Toast;public class KeChengChaXunActivity extends Activity {private TableLayout courseTable;private EditText courseNameEtext;private Spinner academySpinner;private Button academyButton;private Button courseNameButton;private String academySpinnerValue;private String couresName;private KCInteractiveWebHelper kh;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.kechengchaxun);kh = new KCInteractiveWebHelper();findView();// Create an ArrayAdapter using the string array and a default spinner layoutArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.academy_name,android.R.layout.simple_spinner_item);// Specify the layout to use when the list of choices appearsadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);// Apply the adapter to the spinneracademySpinner.setAdapter(adapter);academySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {academySpinnerValue = academySpinner.getSelectedItem().toString();Log.v("spinnerValue", academySpinnerValue);}@Overridepublic void onNothingSelected(AdapterView<?> arg0) {Log.v("spinnerValue", "nothing selected");}});academyButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new MyTask1().execute();}});courseNameButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new MyTask2().execute();}});}void findView() {courseTable = (TableLayout) findViewById(R.id.kccx_course_table);courseNameEtext = (EditText) findViewById(R.id.kccx_course_name);academySpinner = (Spinner) findViewById(R.id.kccx_spinner1);academyButton = (Button) findViewById(R.id.kccx_chaxun1);courseNameButton = (Button) findViewById(R.id.kccx_chaxun2);}/** * * @ClassName: MyTask1 * @Description: 根据学院名查询课程的AsyncTask内部类 * @author zhuzhp * @date 2014年4月8日 下午8:24:37 */private class MyTask1 extends AsyncTask<String, Integer, String> {List<Course> resultList = new ArrayList<Course>();int i = 0;@Overrideprotected String doInBackground(String... params) {Log.v("spinnerValueInBackground", academySpinnerValue);resultList = kh.coursQueryByDepart(academySpinnerValue);return "flag";}@Override/** * 该主要完成将查询得到的数据以tablerow形式显示。 */protected void onPostExecute(String result) {int rows = resultList.size();if (result.equals("flag")) {if (rows != 0) {courseTable.removeAllViewsInLayout();//记得加上这一句,要不然上次查询的结果还是会显示在TableLayout之中//动态生成表格。for ( i = 0; i < rows; i++) {TableRow tablerow = new TableRow(getBaseContext());int k = resultList.get(i).getPropertyCount();//动态生成有边框的单元行,边框的实现是通过table_shape来实现的 ,列的内容来源是从服务端返回得到的List集合里面的内容for (int j = 0; j < k; j++) {TextView text = new TextView(getBaseContext());text.setBackgroundResource(R.drawable.table_shape);//使用shape文件将表格设置成边框显示效果。text.setPadding(1, 1, 1, 1);//给每以列填充显示的内容text.setText(resultList.get(i).getProperty(j).toString());tablerow.addView(text, j);}//这里让自己头疼了很久,因为开始不知道怎样设置某一列的点击事件,汗。。。设置点击监听后,如歌用匿名内部类的话,//String courseDiscription = resultList.get(m).getCoursDisc();因为匿名内部类中取不到外部类的非静态变量的值,所以采用自定义的监听类//记得要自定义一个构造函数,并定义一个参数m,这样好把这里的i的值传入到myListener中的String courseDiscription = resultList.get(m).getCoursDisc();//语句中的m,要不然会报错。tablerow.getChildAt(1).setOnClickListener(new myListener(i));courseTable.addView(tablerow);}} else {Toast.makeText(getBaseContext(), "无相关课程!",Toast.LENGTH_SHORT).show();}}}private class myListener implements OnClickListener{int m = 0;public myListener(int i) {super();this.m = i;}@Overridepublic void onClick(View v) {String courseDiscription = resultList.get(m).getCoursDisc();ParamFromCodeDialogFrag courseDiscDialog = new ParamFromCodeDialogFrag().courseInfoDalog("课程简介", courseDiscription);courseDiscDialog.show(getFragmentManager(), "courseDialog");}}}在这只给出了一个按钮的监听事件的代码,另外一个完全类似。首先是以个spinner的实现,这应该没什么好讲的,在文档中都有例子。主要讲下继承了 AsyncTask的 MyTask1类, AsyncTask 是android中实现异步机制之一,另外一种方式是 Handler模式。 AsyncTask的定义如下: public abstract class AsyncTask<Params, Progress, Result> {}
三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。在特定场合下,并不是所有类型都被使用,如果没有被使用,可以用java.lang.Void类型代替。
一个异步任务的执行一般包括以下几个步骤:
1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5. onPostExecute(Result result), 当后台操作结束时, 此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。 AsyncTask的具体使用请参考一个大神的博客在 MyTask1类中, doInBackground()方法主要是从webservice获得集合 resultList,hk是负责与webservice交互的 KCInteractiveWebHelper 类的对象。这里主要讲下 onPostExecute(String result)方法里面的内容: 首先记得加上这一句: courseTable .removeAllViewsInLayout();要不然显示的效果会是这样
他会把上一次查询结果也显示出来。同时,这里也就要解释下前面的,为什么添加 kccx_course_table TableLayout , 如果不添加的话,在执行 removeAllViewsInLayout()方法时会将 移除掉。增加一个TableLayout 虽然会使得标题和显示的内容尺寸大小不一样,但也只能退而求其次了。 还有些内容就在代码中注释, ParamFromCodeDialogFrag是继承了DialogFragment的类,它主要用于显示提示信息,在这里用于显示课程简介。它的具体实现请参考 这里 ,只是要改变下参数的类型。 最后贴几张效果图
更多相关文章
- Android之GridLayout用法
- Android之fragment点击切换和滑动切换结合
- Android(安卓)开发艺术探索笔记(23)
- Windows Phone SDK 7.1 移动开发必修课
- 学习Android(安卓)Studio开发工具之Activity1
- Android显示概述
- android 输入法(包括手写界面)
- Kotlin Android(安卓)UI利器之Anko Layouts
- 【构建Android缓存模块】(一)吐槽与原理分析