android应用面试宝典(下);用自定义组件控制循环组件使用bug还添加标志显示答案标志位;通过包名读取配置文件AndroidManifest.xml

simpleadapter重用循环组件不好控制,用自定义组件;先满足整体,个别问题可以用标签标记

PackageInfo info= getPackageManager().getPackageInfo("com.kane.interviewcollection",0);

http://download.csdn.net/detail/u010026901/7132059 资源下载

CoverActivity加载全局类(加载dbc)

package com.kane.interviewcollection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import com.kane.interviewcollection.util.Globals;
import com.kane.interviewcollection.util.QuesstionDAOUtils;


import android.os.Bundle;
import android.widget.TextView;
import android.R.bool;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;


public class CoverActivity extends Activity {
private TextView verionText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Globals.init(this);// 只用初始化一次,界面都一样大小
setContentView(R.layout.activity_cover);
verionText=(TextView)findViewById(R.id.verson_text);
//版本信息,读取配置文件AndroidManifest.xml,可以读取整个配置文件信息
try {
PackageInfo info= getPackageManager().getPackageInfo(
"com.kane.interviewcollection",0);

verionText.setText("版本:needkane"+info.versionName);
} catch (NameNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}


Thread thread = new Thread() {
public void run() {
try {
// 从sharedpreferences中读取
// 一个标志位,判断是否读取过题库数据,已经读过了,就加延时,没读过就读取数据
SharedPreferences s = getSharedPreferences(
"quesstion_flag", MODE_PRIVATE);// 只有自己的包私有调用

boolean saveFlag = s.getBoolean("flag", false);// 默认没保存过数据
if (saveFlag) {
// 已经写过数据了,睡1.5秒
sleep(1500);


} else {
System.out.println("123");
// 之前没保存过数据,或没保存好(打开一下就强关程序),需要重新加载数据
// 先删除
QuesstionDAOUtils.deleteAll();
// 读取数据
InputStream is = getAssets().open("question.txt");
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "GBK"));// InputStreamReader转码
String line = null;// 一行数据
StringBuilder question = new StringBuilder();// builder更适合多线程,buffer适合单线程
StringBuilder answer = new StringBuilder();
// 标识当前读入的是问题还是答案
boolean questionFlag = false;
while ((line = reader.readLine()) != null) {
// 判断读入什么,在txt中标示了QUESTION_START_FLAG后面跟的是问题
if ("QUESTION_START_FLAG".equals(line)) {
// 下面读入问题
questionFlag = true;


} else if ("ANSWER_START_FLAG".equals(line)) {
// 读入答案
questionFlag = false;
} else if ("END_FLAG".equals(line)) {
// 将数据保存到数据库中
// 需要建立一个Map,保存问题与答案
Map<String, Object> map = new HashMap<String, Object>();
map.put("question", question.substring(0,
question.length() - 2));// 忽略最后的换行符'\r\n'
map.put("answer", answer.substring(0,
answer.length() - 2));
// 添加到数据库
QuesstionDAOUtils.insert(map);


// 将问题和答案的Builder清空,以便保存新的内容.
question = new StringBuilder();
answer = new StringBuilder();
} else {
// 读入的是数据,需要加入到问题或答案中
if (questionFlag) {
question.append(line + "\r\n");
} else {
answer.append(line + "\r\n");
}
}

}

//存一个标志
Editor e=s.edit();
e.putBoolean("flag", true);
//提交
e.commit();

}
Intent intent = new Intent(CoverActivity.this,
MainActivity.class);
startActivity(intent);
// 这里终结封面的activity,使得不会返回到该界面
finish();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
};
thread.start();
}
}

公共基本activity,为了对公共界面的操作

package com.kane.interviewcollection.util;
import com.kane.interviewcollection.MainActivity;
import com.kane.interviewcollection.QuesstionActivity;
import com.kane.interviewcollection.R;
import com.kane.interviewcollection.SearchActivity;
import android.R.integer;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
/**
 * 防止调用这个进入界面,所以定义成抽象类
 * 
 * @author lenovo
 * 
 */
public abstract class BaseActivity extends Activity {
TextView titleText;
private Button settingBtn;
// 下面的三个按钮
private Button[] bottomBtns = new Button[3];
// 准备目标的Activity,因为下面的按钮跳转是公共的,写在这个BaseActivity
private Class[] targetActivities = { MainActivity.class,
QuesstionActivity.class, SearchActivity.class };
// 未选中的按钮图片
private int[] allBottomImgs = { R.drawable.bottom_icon01_a,
R.drawable.bottom_icon02_a, R.drawable.bottom_icon03_a };
// 选中的按钮图片
private int[] allBottomImgsSelected = { R.drawable.bottom_icon01_b,
R.drawable.bottom_icon02_b, R.drawable.bottom_icon03_b };
// 声明循环为了在内部类使用
private int i;
// 点击设置按钮的浮动窗口
private PopupWindow win;


/**
 * 这里不需要界面
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExitApplication.getInstance().addActivity(this);//每个activity创建的时候添加到activity列表
}
/**
 * 在子类activity中调用的初始化方法
 * 
 * @param title
 * @param selectedBtn
 */
public void init(String title, int selectedBtn) {
// 分别取得公共界面的组件
settingBtn = (Button) findViewById(R.id.settingBtn);
titleText = (TextView) findViewById(R.id.title);
bottomBtns[0] = (Button) findViewById(R.id.bottom01);
bottomBtns[1] = (Button) findViewById(R.id.bottom02);
bottomBtns[2] = (Button) findViewById(R.id.bottom03);
// 每个界面的标题不一样
titleText.setText(title);
// 循环为底部的按钮加入监听,这里的i内部类要用,在外面声明了
for (i = 0; i < bottomBtns.length; i++) {
// 定义个临时变量,防止i一直自增,因为循环完一边后i已经是2了,第二次循环一开始内部类中就是3了
final int temp = i;

if (i == selectedBtn) {
// 选中的
bottomBtns[i].setBackgroundResource(allBottomImgsSelected[i]);
} else {
// 没有选中的
bottomBtns[i].setBackgroundResource(allBottomImgs[i]);
// 加入监听
bottomBtns[i].setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 加入切换界面操作
Intent in = new Intent(BaseActivity.this,
targetActivities[temp]);
startActivity(in);


}
});
}
}
/**
 * 设置按钮的监听事件
 */
settingBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 没有浮动框要添加
if (win == null) {
// 先设置宽高,再设置界面
win = new PopupWindow(Globals.SCREEN_WIDTH / 4,
Globals.SCERRN_HEIGHT / 6);
View view = LayoutInflater.from(BaseActivity.this).inflate(
R.layout.float_window, null);
win.setContentView(view);
// 加入这些内部按钮的监听
TextView versionText = (TextView) view
.findViewById(R.id.show_version);
TextView authText = (TextView) view
.findViewById(R.id.about_author);
TextView exitText = (TextView) view.findViewById(R.id.exit);
versionText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(BaseActivity.this, "当前版本是: 1.0",
Toast.LENGTH_LONG).show();
win.dismiss();// 关闭窗口
}
});
authText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Builder builder = new Builder(BaseActivity.this);
builder.setTitle("提示");
builder.setMessage("本作品由needkane发布,欢迎使用");
builder.setNegativeButton("关闭",
new DialogInterface.OnClickListener() {
@Override
public void onClick(
DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
});
builder.create().show();
win.dismiss();// 浮动窗口消失
}
});
exitText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 退出程序
}
});
}
if (win.isShowing()) {
// 隐藏
win.dismiss();
} else {
// 显示
win.showAsDropDown(settingBtn);
}
}
});
}


@Override
protected void onDestroy() {
//每个activity销毁的时候从activity列表删除

super.onDestroy();
}
}

activity类

package com.kane.interviewcollection;
import com.kane.interviewcollection.util.BaseActivity;
import com.kane.interviewcollection.util.DialogManager;
import android.os.Bundle;
import android.app.Activity;
import android.view.KeyEvent;
import android.view.Menu;


public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
super.init("程序员面试宝典", 0);//第一个底部button点击
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
new DialogManager().showExitHit(this);
return false;//执行上面,而不是默认的关闭activity
}
return super.onKeyDown(keyCode, event);//其他键原有功能保存
}
}

对话框操作类

package com.kane.interviewcollection.util;
import com.kane.interviewcollection.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
public class DialogManager {


public void showExitHit(final Activity act) {
final AlertDialog alertDialog = new AlertDialog.Builder(act)
.setTitle(R.string.exitHint)
.setMessage(R.string.exitChoose)
.setPositiveButton(R.string.sure,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
ExitApplication.getInstance().exit();
}
})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
return;
}
}).create();//先创建,才能show
alertDialog.show();
}
}

退出程序操作类

package com.kane.interviewcollection.util;
import java.util.LinkedList;
import java.util.List;
import android.app.Activity;
import android.app.Application;

public class ExitApplication extends Application {
private List<Activity> activityList = new LinkedList<Activity>();
private static ExitApplication instance;

private ExitApplication() {
}


// 单例模式中获取唯一的ExitApplication实例
public static ExitApplication getInstance() {
if (null == instance) {
instance = new ExitApplication();
}
return instance;
}


// 添加Activity到容器中
public void addActivity(Activity activity) {
activityList.add(activity);
}

// 遍历所有Activity并finish


public void exit() {
for (Activity activity : activityList) {
activity.finish();//先得全部遍历关掉
}
System.exit(0);
}
}

问题列表类

package com.kane.interviewcollection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import com.kane.interviewcollection.adapter.QuestionAdapter;
import com.kane.interviewcollection.util.BaseActivity;
import com.kane.interviewcollection.util.QuesstionDAOUtils;


public class QuesstionActivity extends BaseActivity {
private ListView listView;
private QuestionAdapter adapter;
private List<Map<String, Object>> allValues=new ArrayList<Map<String,Object>>();
//声明几个分页的变量
private int pageNo=1;
private int pageSize=20;
private int count=0;
private int allPages=0;
private String keyword="";
//为了调用滑动事件中的内部类的另一个方法的参数
private int first;
private int visCount;
private int total;

private TextView footerText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quesstion);
//接收关键字
keyword=getIntent().getStringExtra("keyword");
if (keyword==null) {
 super.init("全部问题",1);
 keyword="";
}
else{
//如果有关键词传入
super.init("搜索:"+keyword,1);
}
listView=(ListView)findViewById(R.id.list);
allValues=QuesstionDAOUtils.listDataPage(pageNo,pageSize,keyword);
//查询记录数
count=QuesstionDAOUtils.getAllCount(keyword);
//计算总页数
allPages=(count-1)/pageSize+1;

//加入一个提示的底部信息,每次下拉到分页的最后一个item
footerText=new TextView(this);
footerText.setText("z正在查询,请稍后.............");
footerText.setTextColor(Color.BLACK);
footerText.setTextSize(14);
listView.addFooterView(footerText);

//把数据加入到adapter里
adapter=new QuestionAdapter(this, allValues);
listView.setAdapter(adapter);
//加入监听,点击后才可以看到答案
listView.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
//取得数据
Map<String,Object> map=allValues.get(arg2);
LinearLayout line =(LinearLayout)arg1;//arg1是当前行界面
if(line.getChildCount()==1){//里面只有问题那一个textview
//加入答案的textview
TextView text = new TextView(QuesstionActivity.this);
text.setText(map.get("answer").toString());
text.setTextSize(14);
text.setTextColor(Color.RED);
line.addView(text);
map.put("showFlag", true);
}
else{
//删除答案提示
line.removeViewAt(1);
map.put("showFlag", false);
}
}
});
/**
 * 滑动列表事件
 */
listView.setOnScrollListener(new OnScrollListener(){
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
first = firstVisibleItem;
visCount = visibleItemCount;
total = totalItemCount;

}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==OnScrollListener.SCROLL_STATE_IDLE&&
first+visCount==total&&total!=0){
if(pageNo<allPages){
//可以查询下一条数据
pageNo++;
//将新查询的数据合并到原有的数据集合
allValues.addAll(QuesstionDAOUtils.listDataPage(pageNo,
pageSize,keyword));

//通知界面修改
adapter.notifyDataSetChanged();
}
else{
// 已经查询了全部的数据,将footer删除
if (listView.getFooterViewsCount() > 0) {
listView.removeFooterView(footerText);
}
}
}

}});
}
}

questionadapter类

package com.kane.interviewcollection.adapter;
import java.util.List;
import java.util.Map;
import com.kane.interviewcollection.R;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;


public class QuestionAdapter extends BaseAdapter {
private Context ctx;//哪个activity需要调用自定义的adapter
private List<Map<String,Object>> allValues;
public QuestionAdapter(Context ctx,List<Map<String,Object>> allValues){
this.ctx=ctx;
this.allValues=allValues;
}
@Override
public int getCount() {

return allValues.size();
}


@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return allValues.get(position);
}


@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null) {
convertView=LayoutInflater.from(ctx).inflate(R.layout.question_line, null);
}
else {
//如果这一行是循环重用的组件,需要注意,将展开的内容给删除,不能所有对应循环到该位置的组件都展开,解决BUG,第一页的第四个点开,则每一页第四个都点开
LinearLayout line=(LinearLayout)convertView;
if (line.getChildCount()==2) {
line.removeViewAt(1);//移除答案
}

}
TextView questionText=(TextView)convertView.findViewById(R.id.line_question);
Map<String,Object> map=allValues.get(position);
questionText.setText(map.get("question").toString());
//先前让点开的全部移除了,再一次循环回来的时候是没答案的,所以这里得加个标记
//判断当前行是否要显示答案
if ((Boolean)map.get("showFlag")) {
//动态将答案显示出来
LinearLayout line=(LinearLayout)convertView;
TextView text = new TextView(ctx);
text.setText(map.get("answer").toString());
text.setTextSize(14);
text.setTextColor(Color.RED);


line.addView(text);
}

return convertView;
}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 JavaScript 中,使用 `for..of` 或 `forEach` 循环来遍历一个数组或一个类数组对象时,是同步地进行的。如果在循环体内部调用了异步操作(例如调用接口),则会出现问题,因为循环不会等待异步操作完成,就直接执行下一次循环,导致结果不正确。 解决这个问题的方法是使用 `for await..of` 循环,它可以用于遍历支持异步迭代的对象,例如异步生成器和异步迭代器。使用 `for await..of` 循环可以确保在每次循环中等待异步操作完成后再执行下一次循环。 以下是使用 `for await..of` 循环调用接口的示例代码: ```javascript async function fetchData() { const urls = ['api/url1', 'api/url2', 'api/url3']; for await (const data of getData(urls)) { console.log(data); } } async function* getData(urls) { for (const url of urls) { const response = await fetch(url); const data = await response.json(); yield data; } } ``` 在上面的代码中,`fetchData` 函数调用了 `getData` 函数,并使用 `for await..of` 循环遍历异步生成器返回的数据。`getData` 函数接收一个 URL 数组,并使用 `for..of` 循环遍历 URL,调用 `fetch` 方法获取数据,然后使用 `yield` 关键字返回数据给异步生成器。在 `fetchData` 函数中,`for await..of` 循环等待异步生成器返回数据,并输出到控制台。这样就可以确保在每次循环中等待异步操作完成后再执行下一次循环,避免了使用 `forEach` 循环时出现的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值