gpt4 book ai didi

java - 让 RecyclerView 像 Whatsapp 一样更新

转载 作者:行者123 更新时间:2023-11-29 04:20:39 24 4
gpt4 key购买 nike

我正在试用 Volley,所以它对我的项目非常有用。我可以添加东西和移动信息,但我需要应用程序在列表中添加新项目时自行刷新或更新,我个人希望像 Whatsapp 一样流畅。

我怎样才能做到这一点?我在另一个项目中使用了 AsyncTask,但我不知道这是否应该是这里采用的方法。我对 Android 开发有点陌生,这让我对 Volley 有了一些了解。

你能帮我指出正确的方向吗?

下面是我的适配器的代码、我的主要 Activity 以及我发布帖子的位置。我相信这种刷新应该在这 3 个类中的一个中完成。

如果你能帮助我,那将是我知识的重要学习步骤。我感谢那些愿意提供帮助的人!

谢谢! :)

主要 Activity

public class MainActivity extends AppCompatActivity implements NewsAdapter.OnItemClickListener{

//variable to hold the information that we want to pass to another activity
public static final String EXTRA_NEWS = "newspost";

private TextView textviewUsername, textviewUserEmail;
ArrayList<News> newsArrayList;
private LinearLayoutManager mLayoutManager;
RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

if (!SharedPrefManager.getInstance(this).isLoggedIn()){
startActivity(new Intent(this, LoginActivity.class));
finish();
}

textviewUsername = findViewById(R.id.txtViewusername);
textviewUserEmail = findViewById(R.id.txtViewUserEmail);
textviewUsername.setText(SharedPrefManager.getInstance(this).getUser().getUsername());
textviewUserEmail.setText(SharedPrefManager.getInstance(this).getUser().getEmail());
recyclerView = findViewById(R.id.recylerView);

mLayoutManager = new LinearLayoutManager(getApplicationContext());

//Invert the view of the list
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(mLayoutManager);

recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
newsArrayList = new ArrayList<>();

loadProducts();
}

private void loadProducts() {

/*
* Creating a String Request
* The request type is GET defined by first parameter
* The URL is defined in the second parameter
* Then we have a Response Listener and a Error Listener
* In response listener we will get the JSON response as a String
* */
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, Constants.URL_SHOW_NEWS, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
//converting the string to json array object
JSONArray jsonArray = response.getJSONArray("news");

//traversing through all the object
for (int i = 0; i < jsonArray.length(); i++) {
//getting product object from json array
JSONObject jsnews = jsonArray.getJSONObject(i);
//adding the product to product list
String post = jsnews.getString("noticia");
newsArrayList.add(new News(post));
}

//creating adapter object and setting it to recyclerview
NewsAdapter adapter = new NewsAdapter(MainActivity.this, newsArrayList);
recyclerView.setAdapter(adapter);
/* ------ SETTING OUR ADAPTER TO OUR ONCLICKLISTERNER ---------*/
adapter.setOnClickListener(MainActivity.this);

} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Parou aqui", Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Algo de errad nao esta certo", Toast.LENGTH_LONG).show();
}
});

//adding our stringrequest to queue
Volley.newRequestQueue(this).add(request);
}


public void post(View view){
startActivity(new Intent(this, PostNews.class));
}

@Override
public void onItemClick(int position) {
/* -------------- DO WHATEVER YOU WANT WITH THE CLICK EVENT HERE------------------ */
Intent newsDetail = new Intent(this, NewsDetailActivity.class);
News clickedNews = newsArrayList.get(position);

newsDetail.putExtra(EXTRA_NEWS, clickedNews.getNews_post());

startActivity(newsDetail);
}
}

我的适配器

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsAdapterViewHolder> {

private Context context;
private ArrayList<News> newsArrayList;
//creating a listener for the interface with the same name as our interface
private OnItemClickListener xListener;

//making our own custom onClickListener
public interface OnItemClickListener {
void onItemClick(int position);
}

public void setOnClickListener(OnItemClickListener listener){
//used to simulate the onItemClick of a listview
xListener = listener;
}

public NewsAdapter(Context context, ArrayList<News> newsArrayList) {
this.context = context;
this.newsArrayList = newsArrayList;
}

@Override
public NewsAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.news_list, parent, false);
return new NewsAdapterViewHolder(v);
}

@Override
public void onBindViewHolder(NewsAdapterViewHolder holder, int position) {
News currentNews = newsArrayList.get(position);

String post = currentNews.getNews_post();

holder.txtNoticia.setText(post);
}

@Override
public int getItemCount() {
return newsArrayList.size();
}

public class NewsAdapterViewHolder extends RecyclerView.ViewHolder{
public TextView txtNoticia;

public NewsAdapterViewHolder(View itemView) {
super(itemView);
txtNoticia = itemView.findViewById(R.id.txtnewsPost);

//creating the option for when we click on something to work
//-------------------------WARNING--------------------------//
/*THIS IS A TRICK TO USE onItemClick AS YOU WOULD USE IN A LIST VIEW
* IT'S BETTER TO USE HERE (ACCORDING TO THE TUTORIAL THAN USING ON THE *-onBindViewHolder-*)*/
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (xListener != null) {
int position = getAdapterPosition();
//noposition to make sure the position is still valid
if (position != RecyclerView.NO_POSITION){
//onItemclick is the method that we created on the interface
xListener.onItemClick(position);
}
}
}
});
}
}

}

创建帖子的 Activity

public class PostNews extends AppCompatActivity {

private Button btnpostar;
private EditText editTextNewsPost;
private ProgressBar progressBar;
SharedPrefManager sharedPrefManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_news);

editTextNewsPost = findViewById(R.id.EditTextNewsPost);
btnpostar = findViewById(R.id.btnPostar);
progressBar = findViewById(R.id.progressBar3);
progressBar.setVisibility(View.GONE);


}

public void salvarNoticia(View view) {

final User user = sharedPrefManager.getInstance(this).getUser();
final String post = editTextNewsPost.getText().toString();

if (!post.equals("")) {

progressBar.setVisibility(View.VISIBLE);

StringRequest stringRequest = new StringRequest(Request.Method.POST,
Constants.URL_REGISTER_NEWS,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressBar.setVisibility(View.GONE);

try {


JSONObject jsonObject = new JSONObject(response);

Toast.makeText(getApplicationContext(), jsonObject.getString("message"),
Toast.LENGTH_LONG).show();



} catch (JSONException e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}


}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {

progressBar.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "Erro: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {

Map<String, String> params = null;
params = new HashMap<>();
params.put("news_post", post);
params.put("user_FK", String.valueOf(user.getId()));
return params;
}
};

RequestHandler.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);

} else {
Toast.makeText(getApplicationContext(), "Por favor, não poste nada em branco", Toast.LENGTH_LONG).show();
}

}
}

最佳答案

该问题不受特定编程问题的影响,而是指向应用程序架构。但是,我写这个答案是为了分享我在使用此类应用程序方面的一些经验。

据我从您的问题中了解到,您想使用 RecyclerView 在您的应用程序中显示帖子。当用户从应用程序创建帖子/产品或其他人创建帖子/产品时,RecyclerView 需要更新。如果我理解正确,那么你需要牢记以下几点。

  • 您正在 MainActivityonCreate 函数中调用 loadProducts(); 函数,这是正确的。应用程序应在启动时加载需要在 RecyclerView 中显示的所有项目。所以初始化部分是完全没问题的。
  • 现在是更新的部分。您可以根据自己的方便在这里遵循几种不同的方法。做对或做错的问题主要取决于您的应用程序要求,因此我将对它们进行简要介绍。
  • 首先,您可以考虑从服务器按需拉取数据的模型,例如 Facebook。初始产品已加载到您的 RecyclerView 中。当用户想要查看那里是否有任何更新时,他/她可能会下拉 RecyclerView 来刷新数据。我想您已经想到了这一点,我只是涵盖了所有可用的选项。
  • 然后您可能会考虑使用后台服务从服务器中提取数据,该服务将每隔 60 秒或您可能认为根据应用程序要求安全调用的任何时间间隔调用一次 loadProducts 函数。当您的每个拉取请求都有新数据可用时,使用 notifyDataSetChanged 方法相应地更新 RecyclerView
  • 另一个也需要服务器端实现的选项是基于推送通知。当您的应用程序收到推送时,您将调用 loadProducts 函数并相应地更新 RecyclerView。推送既不实时也不可靠。但是,它可能会为您节省大量 API 调用。
  • 您拥有的另一个可用选项是在您的应用程序和服务器端实现 Websocket。开发和性能是昂贵的。但是,这可以确保您的数据实时更新。
  • 最后但并非最不重要的一点是,您可以查看 Google 提供的 Firebase 数据库,它的实现与您的情况完全相同。它在后端架构使用 Websocket 时实时更新,但更容易和更简单地集成到您的应用程序中。

我刚刚给了你一些想法。希望这些可以帮助你。

更新

根据您的评论,我认为您没有清楚地理解我的意思。您无法在服务器端每 x 分钟后收到推送通知,因为在这种情况下,您需要跟踪安装在用户设备中的每个应用程序中的帖子更新 - 这是一个糟糕的设计.

您需要选择一个。如果您想每 x 分钟刷新一次数据,那么我建议在您的应用程序中保留一个 Handler 或一个后台 Service ,它将调用 loadProducts 每 x 分钟后运行一次,并将更新您的数据。

如果您计划实现基于推送通知的更新,那么您可以向服务器端插入的每个新数据上连接的设备发送推送。当应用端收到推送时,你需要用更新后的数据相应地更新列表。希望现在更清楚了。

关于java - 让 RecyclerView 像 Whatsapp 一样更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49436199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com