我在活动中有一个Recycler视图,它无法访问适配器,我知道这个bcoz我已经放了Log.e消息,并且没有任何消息放在适配器中显示
这是我的代码 Phone.java(带回收者视图的活动)
package c.bit.bitscaller;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RelativeLayout;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.widget.Toast;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
import java.util.ArrayList;
import java.util.List;
import c.bit.bitscaller.Adapters.PhoneRecyclerAdapter;
public class phone extends AppCompatActivity {
private boolean bb;
Toolbar toolbar;
ActionBarDrawerToggle actionBarDrawerToggle;
NavigationView navigationView;
DrawerLayout drawerLayout;
private AppCompatActivity activity = phone.this;
private RecyclerView recyclerViewPhone;
private ArrayList<Pojo> list;
private PhoneRecyclerAdapter phoneRecyclerAdapter;
private DatabaseHelper databaseHelper;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone);
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.INTERNET, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CONTACTS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_CALENDAR, Manifest.permission.INTERNET, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
// check if all permissions are granted
if (report.areAllPermissionsGranted()) {
// do you work now
}
// check for permanent denial of any permission
if (report.isAnyPermissionPermanentlyDenied()) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
})
.onSameThread()
.check();
toolbar = (Toolbar) findViewById(R.id.toolbar1);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("PHONE BLACKLIST");
initAndFillData();
navigationView = (NavigationView) findViewById(R.id.navigation_menu);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.phoneblacklist:
drawerLayout.closeDrawers();
break;
case R.id.smsblacklist:
Intent intent1 = new Intent(phone.this, sms.class);
startActivity(intent1);
break;
case R.id.spam_mails:
Intent intent2 = new Intent(phone.this, email.class);
startActivity(intent2);
break;
case R.id.phonelist:
Intent intent3 = new Intent(phone.this, managephonelist.class);
startActivity(intent3);
break;
case R.id.smslist:
Intent intent4 = new Intent(phone.this, managesmslist.class);
startActivity(intent4);
break;
case R.id.about:
Intent intent = new Intent(phone.this, about.class);
startActivity(intent);
break;
}
return false;
}
});
setUpToolbar();
}
public void initAndFillData()
{
recyclerViewPhone = findViewById(R.id.recyclerphone);
list = new ArrayList<>();
Log.e("Error1", "Reached Here 1");
phoneRecyclerAdapter = new PhoneRecyclerAdapter(list, this);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerViewPhone.setLayoutManager(mLayoutManager);
recyclerViewPhone.setItemAnimator(new DefaultItemAnimator());
recyclerViewPhone.setHasFixedSize(true);
recyclerViewPhone.setAdapter(phoneRecyclerAdapter);
databaseHelper = new DatabaseHelper(activity);
getDataFromSQLite();
}
@SuppressLint("StaticFieldLeak")
private void getDataFromSQLite() {
// AsyncTask is used that SQLite operation not blocks the UI Thread.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
list.clear();
list.addAll(databaseHelper.getAllPhoneList());
Log.e("Error3", "Reached Here 3");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
phoneRecyclerAdapter.notifyDataSetChanged();
}
}.execute();
}
private void setUpToolbar() {
drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
toolbar = (Toolbar) findViewById(R.id.toolbar1);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("PHONE BLACKLIST");
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.phone_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.phone_clearlog) {
//code for phone clear log
}
return super.onOptionsItemSelected(item);
}
@Override
//pressing back button twice to exit
public void onBackPressed() {
if (!bb) {
Toast.makeText(this, "press back again to exit", Toast.LENGTH_LONG).show();
bb = true;
} else {
super.onBackPressed();
}
new CountDownTimer(3000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
bb = false;
}
}.start();
}
}
这是我的手机活动xml文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#00bcd4"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerphone"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#00bcd4"
app:headerLayout="@layout/header"
app:menu="@menu/drawer_phone"/>
</android.support.v4.widget.DrawerLayout>
这是我的适配器
package c.bit.bitscaller.Adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import c.bit.bitscaller.Pojo;
import c.bit.bitscaller.R;
public class PhoneRecyclerAdapter extends
RecyclerView.Adapter<PhoneRecyclerAdapter.PhoneViewHolder> {
private ArrayList<Pojo> listPhone;
Context context;
public PhoneRecyclerAdapter(ArrayList<Pojo> listPhone, Context context) {
this.listPhone = listPhone;
this.context = context;
}
public class PhoneViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView number;
public TextView lati;
public TextView longi;
public TextView time;
public TextView date;
public PhoneViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
number = view.findViewById(R.id.number);
lati = view.findViewById(R.id.lati);
longi = view.findViewById(R.id.longi);
time = view.findViewById(R.id.time);
date = view.findViewById(R.id.date);
Log.e("Error 4", "Reached Here 4");
}
}
@Override
public PhoneViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
return new PhoneViewHolder(itemView);
}
@Override
public void onBindViewHolder(final PhoneViewHolder holder, int position) {
holder.name.setText(listPhone.get(position).getName());
holder.number.setText(listPhone.get(position).getNumber());
holder.lati.setText("" + listPhone.get(position).getLati());
holder.longi.setText("" + listPhone.get(position).getLongi());
holder.time.setText(listPhone.get(position).getTime());
Log.e("Error5 ", "Reached Here 5");
holder.date.setText(listPhone.get(position).getDate());
}
@Override
public int getItemCount() {
return listPhone.size();
}
}
继承我的数据库功能以获取
public List<Pojo> getAllPhoneList() {
List<Pojo> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM PhoneTable where BPhone=1 ORDER BY rid DESC", null);
if (cursor.moveToFirst()) {
do {
Pojo listRecord = new Pojo();
listRecord.setNumber(cursor.getString(cursor.getColumnIndex(DatabaseHelper.number)));
listRecord.setLati(cursor.getFloat(cursor.getColumnIndex(DatabaseHelper.lati)));
listRecord.setLongi(cursor.getFloat(cursor.getColumnIndex(DatabaseHelper.longi)));
listRecord.setDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.date)));
listRecord.setTime(cursor.getString(cursor.getColumnIndex(DatabaseHelper.time)));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
Log.e("Error 2 ", "Reached Here 2");
return list;
}
在我的logcat中,错误是
04-13 23:11:56.855 6416-6416/c.bit.bitscaller E/Error1: Reached Here 1
04-13 23:11:56.885 6416-6485/c.bit.bitscaller E/Error 2: Reached Here 2
04-13 23:11:56.885 6416-6485/c.bit.bitscaller E/Error3: Reached Here 3
错误2和3来自数据库,这意味着它们也能正常工作 缺少错误4和5,这是来自适配器,意味着适配器是不可及的(不知何故)
请帮忙(我也检查过是否通过sqlite浏览器及其存在sqlite中的数据)
现在已经有一天了,非常感谢任何帮助。
(我已经发布了代码但由于我的项目负责人通知版权问题而不得不删除)
答案 0 :(得分:1)
在您的代码中发现了一些错误。
这个方法$x
返回Pojo对象的空列表,因为你错过了在迭代器中将pojo对象添加到do里面的列表。
getAllPhoneList()
我做了修改,希望它能正常工作,请按照我的下面的代码进行更改。
从list.add(listRecord);
方法调用此initAndFillData()
,就像您在代码中所做的那样,并在代码下面代替您的代码粘贴
onCreate()
现在将此asyntask方法粘贴到您的活动中
public void initAndFillData()
{
Log.e("Error1", "Reached Here 1");
recyclerViewPhone = findViewById(R.id.recyclerphone);
list = new ArrayList<>();
recyclerViewPhone.setLayoutManager(new LinearLayoutManager(this));
recyclerViewPhone.setItemAnimator(new DefaultItemAnimator());
recyclerViewPhone.setHasFixedSize(true);
new LoadDataFromSqlite().execute();
}
最后将此代码粘贴到databasehelper中的class LoadDataFromSqlite extends AsyncTask<Void, Void, Void>
{
DataBaseHelper dataBaseHelper = new DataBaseHelper(context);
@Override
protected void onPreExecute()
{
super.onPreExecute();
//Show porgressbar if needed.
}
@Override
protected Void doInBackground(Void... voids)
{
// Get the list of pojo objects by calling this below method of databasehelper
list = dataBaseHelper.getAllPhoneList();
return null;
}
@Override
protected void onPostExecute(Void aVoid)
{
super.onPostExecute(aVoid);
// Check if obtained list of pojo size is null, if its null then you have no data in db.
if (list.size() > 0)
{
// pass dataset (list of pojo object) to adapter and set adapter to recylerview
phoneRecyclerAdapter = new PhoneRecyclerAdapter(list, this);
recyclerViewPhone.setAdapter(phoneRecyclerAdapter);
}
}
}
方法
getAllPhoneList()
这必须正常工作。希望它有所帮助。
答案 1 :(得分:0)
LinearLayoutManager使用 getApplicationContext()进行实例化。
LinearLayoutManager负责在适配器中创建视图。 正如您在the rule of thumb中看到的那样,您应该将活动上下文与 this 一起使用。
答案 2 :(得分:0)
您正在后台线程中更新您的列表,但您的recyclerView操作位于UI线程中,因此它实际上并未得到通知。
将方法getDataFromSQLite()
更改为:
@SuppressLint("StaticFieldLeak")
private void getDataFromSQLite() {
// AsyncTask is used that SQLite operation not blocks the UI Thread.
new AsyncTask<Void, Void, ArrayList<Pojo>>() {
@Override
protected Void doInBackground(Void... params) {
Log.e("Error3", "Reached Here 3");
return databaseHelper.getAllPhoneList();
}
@Override
protected void onPostExecute(ArrayList<Pojo> pojos) {
super.onPostExecute(pojos);
list.clear();
list.addAll(pojos);
phoneRecyclerAdapter.notifyDataSetChanged();
}
}.execute();
}
AsyncTask&#39; doInBackground()
方法在一个单独的线程中运行,而在onPostExecute()
中,它将结果传递给UI线程。