java - Android-RecyclerView 从 JSON 中设置图像和文本

标签 java android json string android-fragments

您好,我正在尝试从发送图像 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/

相关文章:

jQuery 自动完成获取 id

php - 使用 Ajax.Request 将 JSON 从浏览器传递到 PHP 的最佳方式

java - 指定部署环境

java - 有没有可以与java集成的语言可以有效地读取大型XLSX文件?

android - 单击按钮从 firebase 数据库中检索数据

android - 滑动并展开 View Android

java - 如何在按 x 按钮时关闭 JOptionPane 消息框?

java - Docker OpenJDK-8 JavaFx

Android动画 View 从右到左

java - 如何使用 jQuery params() 解析深层 URL?