В следующем примере, который я написал, показано, как
Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest
для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.
Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist
для заданного набора строк запроса:
[
"search?type=playlist&q=%22doom%20metal%22",
"search?type=playlist&q=Adele"
]
Для каждого элемента новый Promise запустит блок - ExecutionBlock
, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user
и выполняет новый HTTP-вызов в ExecutionProfileBlock
асинхронно.
Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all
.
NOTE Recent Spotify search
API-интерфейсам потребуется указать токен доступа в заголовках запроса:
-H "Authorization: Bearer {your access token}"
Итак, вы должны запустить следующий пример, вам нужно поместить маркер доступа в заголовки запроса:
var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
log: function(s) {
document.getElementById("console").innerHTML += s + "
"
}
}
// Simple XMLHttpRequest
// based on https://davidwalsh.name/xmlhttprequest
SimpleRequest = {
call: function(what, response) {
var request;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // Internet Explorer
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
}
catch (e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
// State changes
request.onreadystatechange = function() {
if (request.readyState === 4) { // Done
if (request.status === 200) { // Complete
response(request.responseText)
}
else
response();
}
}
request.open('GET', what, true);
request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken);
request.send(null);
}
}
//PromiseAll
var promiseAll = function(items, block, done, fail) {
var self = this;
var promises = [],
index = 0;
items.forEach(function(item) {
promises.push(function(item, i) {
return new Promise(function(resolve, reject) {
if (block) {
block.apply(this, [item, index, resolve, reject]);
}
});
}(item, ++index))
});
Promise.all(promises).then(function AcceptHandler(results) {
if (done) done(results);
}, function ErrorHandler(error) {
if (fail) fail(error);
});
}; //promiseAll
// LP: deferred execution block
var ExecutionBlock = function(item, index, resolve, reject) {
var url = "https://api.spotify.com/v1/"
url += item;
console.log( url )
SimpleRequest.call(url, function(result) {
if (result) {
var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) {
return item.owner.href;
})
resolve(profileUrls);
}
else {
reject(new Error("call error"));
}
})
}
arr = [
"search?type=playlist&q=%22doom%20metal%22",
"search?type=playlist&q=Adele"
]
promiseAll(arr, function(item, index, resolve, reject) {
console.log("Making request [" + index + "]")
ExecutionBlock(item, index, resolve, reject);
}, function(results) { // Aggregated results
console.log("All profiles received " + results.length);
//console.log(JSON.stringify(results[0], null, 2));
///// promiseall again
var ExecutionProfileBlock = function(item, index, resolve, reject) {
SimpleRequest.call(item, function(result) {
if (result) {
var obj = JSON.parse(result);
resolve({
name: obj.display_name,
followers: obj.followers.total,
url: obj.href
});
} //result
})
} //ExecutionProfileBlock
promiseAll(results[0], function(item, index, resolve, reject) {
//console.log("Making request [" + index + "] " + item)
ExecutionProfileBlock(item, index, resolve, reject);
}, function(results) { // aggregated results
console.log("All response received " + results.length);
console.log(JSON.stringify(results, null, 2));
}
, function(error) { // Error
console.log(error);
})
/////
},
function(error) { // Error
console.log(error);
});
Я подробно рассмотрел это решение здесь .
Это поздно, но это может помочь кому-то :) :) Для добавления вида программным способом попробуйте как
LinearLayout rlmain = new LinearLayout(this);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
LinearLayout ll1 = new LinearLayout (this);
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);
setContentView(rlmain, llp);
. Это создаст весь ваш просмотр программно. Вы можете добавить любое количество просмотров одинаково. Надеюсь, это поможет. :)
LinearLayout является подклассом ViewGroup , который имеет метод, называемый addView . Метод addView должен быть таким, каким вы являетесь.
для всех, кто еще заинтересован:
, лучший способ, который я нашел, - использовать статический метод inflate для View.
View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);
, где yourViewXML - это что-то вроде R.layout.myView
обратите внимание, что вам нужна ViewGroup, чтобы добавить представление (это любой макет, о котором вы можете думать)
, так что пример позволяет сказать, что у вас есть фрагмент, который он просматривает уже было завышено, и вы знаете, что корневой вид является макетом, и вы хотите добавить к нему представление:
View view = getView(); // returns base view of the fragment
if (view == null)
return;
if (!(view instanceof ViewGroup))
return;
ViewGroup viewGroup = (ViewGroup) view;
View popup = View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);
Вызов addView
- правильный ответ, но вам нужно сделать немного больше, чтобы заставить его работать.
Если вы создаете представление через конструктор (например, Button myButton = new Button();
), , вам нужно будет вызвать setLayoutParams
в недавно построенном представлении, передав экземпляр внутреннего класса LayoutParams родительского представления, прежде чем вы добавите вновь созданного ребенка в родительское представление.
Например, у вас может быть следующий код в вашей функции onCreate()
, если ваш LinearLayout имеет id R.id.main
:
LinearLayout myLayout = findViewById(R.id.main);
Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
myLayout.addView(myButton);
Важное значение имеет установка параметров LayoutParams. Для каждого представления требуется, по крайней мере, параметр layout_width и параметр layout_height. Также важно получить правильный внутренний класс. Я боролся с тем, чтобы получать представления, добавленные в TableRow, для правильной отображения, пока не выясню, что я не передавал экземпляр TableRow.LayoutParams в setLayoutParams дочернего представления.