您好,我正在尝试从发送图像 URL 和名称的 JSON 制作 RecyclerView 列表(我现在只需要向 RecyclerView 显示这些)。我在过去 2 天尝试了 Google 和 Stack,但仍然没有将文本和图像从 JSON 设置为 RecyclerView 的解决方案 大多数教程使用 Volley 或其他库,并且他们在同一类中使用 AsyncTask(解决数据传递问题问题 )。我没有使用
我已经成功制作了recyclerView,其中包含存储在可绘制文件夹和字符串数组(Values-->String.xml) 中的本地镜像和文本,并且工作正常
但我的情况与大多数解决方案不同
1) 我从 Fragment 的父 Activity 调用 AsyncTask.Execute 方法
2) 我的 AsyncTask 类与调用 AsyncTask.Execute 方法的类不在同一个类中。
3) 我正在尝试从 AsyncTask 中获取 Fragment 中的值,即使在设置 setter 和 getter 方法之后也始终返回 Null(将 Images[] 和 Name[] 传输到 Fragment 时很困难)
4) 当我在 String[] 中获取图像路径时,如何将路径设置到 Recycler View 中
这是我的类(class)
***从我调用 AsyncTask.Execute 方法的地方。
public class Navigation_Drawer extends AppCompatActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle Item Selection
switch (item.getItemId()){
case R.id.action_websearch:
Toast.makeText(getBaseContext(), "You have Clicked WebSearch", Toast.LENGTH_LONG).show();
break;
case R.id.parseJson:
new JsonParsing().execute();//AYSNCTASK EXECUTE
}
然后那个Aysnctask执行调用了这个类
public class JsonParsing extends AsyncTask<String, Void, List<String[]>> {
private String URL_Path="http://www.example.com/test/Android/Data/showUers.php";
private static final String TAG="JSON PARSER******";
HttpURLConnection connection;
BufferedReader reader;
private Context context;
@Override
protected String[] doInBackground(String... params) {
try {
URL url=new URL(URL_Path);
connection= (HttpURLConnection) url.openConnection();
connection.connect();
Log.d(TAG,connection.toString());
InputStream inputStream=connection.getInputStream();
reader=new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuffer stringBuffer=new StringBuffer();
while ((line=reader.readLine())!=null){
stringBuffer.append(line);
}
String completeJSON=stringBuffer.toString();
JSONArray parentArray=new JSONArray(completeJSON);
String[] Name=new String[parentArray.length()];
String[] ImagePath=new String[parentArray.length()];
for (int i = 0; i <parentArray.length() ; i++) {
JSONObject childObject=parentArray.getJSONObject(i);
String Fname=childObject.getString("First_Name") ;
String Lname=childObject.getString("Last_Name") ;
Name[i]=Fname+" "+Lname;
ImagePath[i]=childObject.getString("Image");
Log.d(TAG,"String Arrays "+Name[i]+" "+ ImagePath[i]);
//THIS LOG SUCCESSFULLY SHOWING RESULT IN LOG
}
List<String[]> results=new ArrayList<>(2);
results.add(Name);
results.add(ImagePath);
return results;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
try {
connection.disconnect();
if (reader!=null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(List<String[]> results) {
Log.d(TAG,"ON POST EXECUTE CALLING START");
String[] Name=results.get(0);
String[] Image=results.get(1);
Log.d(TAG,"ON POST EXECUTE CALLING Bundle");
FriendsList friendsListFragment=new FriendsList();
Bundle dataToPass=new Bundle();
dataToPass.putStringArray("Names",Name);
dataToPass.putStringArray("ImagePath",Image);
friendsListFragment.setArguments(dataToPass);
friendsListFragment.getData(dataToPass);
Log.d(TAG,"ON POST EXECUTE CALLING LAST "+Name.toString());
}
这是我调用 RecyclerView 的 fragment
public class FriendsList extends Fragment {
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
TypedArray Image;
public static final String TAG="Friends List******";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.activity_friend_list,container,false);
recyclerView= (RecyclerView) view.findViewById(R.id.RecyclerViewForFriendList);
Name=getResources().getStringArray(R.array.left_Drawer_Menu);
Image=getResources().obtainTypedArray(R.array.user_image);
recyclerView.setHasFixedSize(true);
adapter=new RecyclerFriendListAdapter(getActivity(),Name,Image);
recyclerView.setAdapter(adapter);
recyclerView.setAdapter(adapter);
layoutManager=new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
String[] Name=getArguments().getStringArray("Names");//Returns Null
String[] Image=getArguments().getStringArray("ImagePath");
return view;
}
public void getData(Bundle savedInstanceState){
if (savedInstanceState!=null) {
Log.d(TAG, "GET DATA CALLING ");
String[] New_Name = getArguments().getStringArray("Names");
String[] New_ImagePath =getArguments().getStringArray("ImagePath");
Log.d(TAG, "ON CREATE SETTING NAME AND IMAGEPATH INTO ARRAY " + New_ImagePath[2]+" "+New_Name[1]);
adapter=new RecyclerFriendListAdapter(getActivity(),New_Name,New_ImagePath);
recyclerView.setAdapter(adapter);//*************RETURNS NULL
Log.d(TAG, "GET DATA CALLING FINISHED ");
}
}}
回收器适配器类
public class RecyclerFriendListAdapter extends RecyclerView.Adapter<RecyclerFriendListAdapter.ViewHolder> {
String[] Name,ImagePath;
TypedArray Image;
Context context;
static final String TAG="FRIEND LIST ADAPTER****";
public RecyclerFriendListAdapter(Context context,String[] name,TypedArray image) {
this.context = context;
Image = image;
Name = name;
}
public RecyclerFriendListAdapter(Context context,String[] image, String[] name) {
this.context=context;
ImagePath = image;
Name = name;
}
@Override
public RecyclerFriendListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater= (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=layoutInflater.inflate(R.layout.listview_item_recycler,null);
Log.d(TAG,"Constructor Calling");
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerFriendListAdapter.ViewHolder holder, int position) {
Log.d(TAG,"Holder "+position);
holder.UserImage.setImageResource(Image.getResourceId(position,0));
holder.Name.setText(Name[position]);
}
@Override
public int getItemCount() {
return Name.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView Name;
ImageView UserImage;
Context context;
public ViewHolder(View v) {
super(v);
Log.d(TAG,"View Holder");
Name= (TextView) v.findViewById(R.id.User_Name_Item);
UserImage= (ImageView) v.findViewById(R.id.UserImage);
}
}
我知道我在代码中犯了一些错误但是我需要做这些事情
从 doinbackground 获取图像和名称字符串数组,然后在 Fragment 中获取这些值,并将这两个数组发送到 RecyclerView Adapter 以显示在 recyclerview 列表中。
这是一个小问题,只有专家才能解决这个问题,所以请帮我解决这个问题
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new JsonParsing.execute();
showSkipButton(true);
setProgressButtonEnabled(true);
}
@Override
public void onDonePressed(Fragment currentFragment) {
super.onDonePressed(currentFragment);
Intent intent=new Intent(this,Parent_Activty.class);
startActivity(intent);
}
这是附加 fragment 的父 Activity
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parent_layout);
//First set up toolbar
setupToolbar();
//Add the Fragment to the container
FragmentTransaction transaction=getFragmentManager().beginTransaction();
FriendsList friendList=new FriendsList();
transaction.replace(R.id.Parent_Main_Layout,friendList);
transaction.commit();
}
作为@Cricket_007 建议和包装类的新接口(interface)
public interface onResultReceived {
public void onResultRececivedFuc(List<String[]> users);
}
包装类
public class WrapperClass {
String[] Name,Image;
public String[] getName() {
return Name;
}
public void setName(String[] name) {
Name = name;
}
public String[] getImage() {
return Image;
}
public void setImage(String[] image) {
Image = image;
}
}
最后是我的日志
08-07 02:17:57.490 32184-32184/com.recyclerview_pro_working1 D/Friends List******: ON CREATE CALLING
08-07 02:17:57.490 32184-32184/com.recyclerview_pro_working1 D/Friends List******: ON CREATE VIEW START
08-07 02:17:57.490 32184-32184/com.recyclerview_pro_working1 D/Friends List******: PUTTING VALUE INTO NAME AND IMAGE
08-07 02:17:57.490 32184-32184/com.recyclerview_pro_working1 D/Friends List******: ON CREATE VIEW [Ljava.lang.String;@437092e0
08-07 02:17:57.550 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.550 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.550 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 0
08-07 02:17:57.600 32184-32188/com.recyclerview_pro_working1 D/dalvikvm: GC_CONCURRENT freed 1791K, 42% free 24608K/41927K, paused 2ms+3ms, total 33ms
08-07 02:17:57.600 32184-32184/com.recyclerview_pro_working1 D/dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 17ms
08-07 02:17:57.640 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.640 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.640 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 1
08-07 02:17:57.650 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.650 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.650 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 2
08-07 02:17:57.660 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.660 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.660 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 3
08-07 02:17:57.670 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.670 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.670 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 4
08-07 02:17:57.680 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.680 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.680 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 5
08-07 02:17:57.680 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Constructor Calling
08-07 02:17:57.680 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: View Holder
08-07 02:17:57.690 32184-32184/com.recyclerview_pro_working1 D/FRIEND LIST ADAPTER****: Holder 6
08-07 02:17:57.700 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position0
08-07 02:17:57.700 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position1
08-07 02:17:57.710 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position2
08-07 02:17:57.720 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position3
08-07 02:17:57.720 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position4
08-07 02:17:57.730 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position5
08-07 02:17:57.730 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position6
08-07 02:17:57.740 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position7
08-07 02:17:57.740 32184-32184/com.recyclerview_pro_working1 D/ADAPTER*********: Value of Position8
08-07 02:18:19.830 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: DO IN BACKGROUND START
08-07 02:18:20.580 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: libcore.net.http.HttpURLConnectionImpl:DOMAIN NAME/test/Android/Data/showUers.php
08-07 02:18:21.200 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: GET INPUT STREAM AND PUUTING INTO READER
08-07 02:18:21.200 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: JSON ARRAY START
08-07 02:18:21.210 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: String Arrays Julien Blin DOMAIN NAME/test/Android/Data/uploads/Julien.jpg
08-07 02:18:21.210 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: String Arrays Iveta Benesova DOMAIN NAME/test/Android/Data/uploads/Iveta.jpg
08-07 02:18:21.210 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: String Arrays Varun Razora DOMAIN NAME/test/Android/Data/uploads/Varun.jpg
08-07 02:18:21.210 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: JSON PARSING FINISHED
08-07 02:18:21.210 32184-3367/com.recyclerview_pro_working1 D/JSON PARSER******: Return Statement
08-07 02:18:21.210 32184-32184/com.recyclerview_pro_working1 D/JSON PARSER******: ON POST EXECUTE CALLING START
08-07 02:18:21.210 32184-32184/com.recyclerview_pro_working1 D/JSON PARSER******: ON POST EXECUTE CALLING STOP
08-07 02:18:21.210 32184-32184/com.recyclerview_pro_working1 D/Friends List******: GET DATA CALLING
08-07 02:18:21.210 32184-32184/com.recyclerview_pro_working1 D/Friends List******: ON CREATE SETTING NAME AND IMAGEPATH INTO ARRAY DOMAIN NAME/test/Android/Data/uploads/Varun.jpg Iveta Benesova
08-07 02:18:21.210 32184-32184/com.recyclerview_pro_working1 D/AndroidRuntime: Shutting down VM
08-07 02:18:21.210 32184-32184/com.recyclerview_pro_working1 W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x416dd378)
08-07 02:18:21.220 32184-32184/com.recyclerview_pro_working1 E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.recyclerview_pro_working1.mainScreenFragments.FriendsList.getData(FriendsList.java:99)
at com.recyclerview_pro_working1.Sending_Image_To_Server.onPostExecute(Sending_Image_To_Server.java:130)
at com.recyclerview_pro_working1.Sending_Image_To_Server.onPostExecute(Sending_Image_To_Server.java:29)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:4787)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)
EDIT #1 正如@Hendra Wijaya Djiono 建议我编辑我的代码并且它仍然返回 Null 我认为它更多的原因是在没有值(value)时启动 fragment (我之前也调用过 AsyncTask)我从哪里开始这样的家长 Activity
EDIT #2 因为 @Hendra Wijaya Djiono 和 @cricket_007 都建议这两个答案都按我的预期工作,但@Hendra Bundle Point 似乎很容易和清晰的 @cricket_007 代码建议避免 bundle 我同意他的观点,当创建 Fragment 时 bundle 将为 null 但只是为了应用程序工作我更新了日志并将其发送数据编码为通过 bundle 成功地 fragment 但是它首先带来了 2 个问题你可以看到 recyclerview.setAdapter(adapter) throws null pointer 以及如何在适配器中将 imagePath(图像的 URL)设置为 ImageView。
编辑 #3 @Cricket_007 建议我添加接口(interface)和包装器类,但将字符串(名称[] 和图像[])放入列表 List=new ArrayList();让我很难过。所以我使用了 Noraml 列表函数并将两个字符串放入其中,然后将其放入 onPostExecute。
最佳答案
老实说,您提供的代码不够干净/健壮,但为了给您一些见解,我将使用您提供的代码。 第一个,如果你想同时传递 String[] Name 和 ImagePath,你可以制作一个二维数组或将两者都放入 List 或任何东西作为包装器
public class JsonParsing extends AsyncTask<String, Void, List<String[]>> {
private String URL_Path = "http://www.example.com/test/Android/Data/showUers.php";
private static final String TAG = "JSON PARSER******";
HttpURLConnection connection;
BufferedReader reader;
private Context context;
@Override
protected String[] doInBackground(String... params) {
try {
URL url = new URL(URL_Path);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
Log.d(TAG, connection.toString());
InputStream inputStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuffer stringBuffer = new StringBuffer();
while ((line = reader.readLine()) != null) {
stringBuffer.append(line);
}
String completeJSON = stringBuffer.toString();
JSONArray parentArray = new JSONArray(completeJSON);
String[] Name = new String[parentArray.length()];
String[] ImagePath = new String[parentArray.length()];
for (int i = 0; i < parentArray.length(); i++) {
JSONObject childObject = parentArray.getJSONObject(i);
String Fname = childObject.getString("First_Name");
String Lname = childObject.getString("Last_Name");
Name[i] = Fname + " " + Lname;
ImagePath[i] = childObject.getString("Image");
Log.d(TAG, "String Arrays " + Name[i] + " " + ImagePath[i]);
//THIS LOG SUCCESSFULLY SHOWING RESULT IN LOG
}
List<String[]> result = new ArrayList<>(2);
result.add(Name);
result.add(ImagePath);
return result; // CONFUSE IN HOW TO RETURN 2 ARRAY STRING NAME AND IMAGE
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
try {
connection.disconnect();
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(List<String[]> results) {
//SOMETHING TODO WITH RESULTS
String[] Name = results.get(0);
String[] ImagePath = results.get(1);
}
}
要将结果从 Activity 传递到您的 fragment ,您可以使用 Bundle
FriendsList friendsListFragment = new FriendsList();
Bundle dataToPass = new Bundle();
dataToPass.putStringArray("names", Name);
dataToPass.putStringArray("imagePaths", ImagePath);
friendsListFragment.setArguments(dataToPass);
在你的 fragment 上,你可以获得数据
String[] names = getArguments().getStringArray("names");
String[] imagePaths = getArguments().getStringArray("imagePaths");
在你的 RecyclerView 适配器上,创建一个构造函数来传递数据
private String[] dataName, dataImagePath;
public RecyclerFriendListAdapter(Context context, String[] dataName, String[] dataImagePath) {
this.context = context;
this.dataName = dataName;
this.dataImagePath = dataImagePath;
}
然后您可以通过该构造函数将数据从 fragment 传递到适配器
关于java - Android-RecyclerView 从 JSON 中设置图像和文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38780310/